xref: /reactos/dll/cpl/usrmgr/users.c (revision 8532f187)
1 /*
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
6  *
7  * PROGRAMMERS:     Eric Kohl
8  */
9 
10 /*
11  * TODO:
12  *  - Add new user to the users group.
13  *  - Remove a user from all groups.
14  *  - Use localized messages.
15  */
16 
17 #include "usrmgr.h"
18 
19 typedef struct _USER_DATA
20 {
21     HMENU hPopupMenu;
22 
23     INT iCurrentItem;
24 
25 } USER_DATA, *PUSER_DATA;
26 
27 
28 
29 static BOOL
CheckPasswords(HWND hwndDlg,INT nIdDlgItem1,INT nIdDlgItem2)30 CheckPasswords(HWND hwndDlg,
31                INT nIdDlgItem1,
32                INT nIdDlgItem2)
33 {
34     TCHAR szPassword1[PWLEN];
35     TCHAR szPassword2[PWLEN];
36     UINT uLen1;
37     UINT uLen2;
38 
39     uLen1 = GetDlgItemText(hwndDlg, nIdDlgItem1, szPassword1, PWLEN);
40     uLen2 = GetDlgItemText(hwndDlg, nIdDlgItem2, szPassword2, PWLEN);
41 
42     /* Check the passwords */
43     if (uLen1 != uLen2 || _tcscmp(szPassword1, szPassword2) != 0)
44     {
45         MessageBox(hwndDlg,
46                    TEXT("The passwords you entered are not the same!"),
47                    TEXT("ERROR"),
48                    MB_OK | MB_ICONERROR);
49         return FALSE;
50     }
51 
52     return TRUE;
53 }
54 
55 
56 INT_PTR CALLBACK
ChangePasswordDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)57 ChangePasswordDlgProc(HWND hwndDlg,
58                       UINT uMsg,
59                       WPARAM wParam,
60                       LPARAM lParam)
61 {
62     PUSER_INFO_1003 userInfo;
63 
64     UNREFERENCED_PARAMETER(wParam);
65 
66     userInfo = (PUSER_INFO_1003)GetWindowLongPtr(hwndDlg, DWLP_USER);
67 
68     switch (uMsg)
69     {
70         case WM_INITDIALOG:
71             userInfo = (PUSER_INFO_1003)lParam;
72             SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
73             break;
74 
75         case WM_COMMAND:
76             switch (LOWORD(wParam))
77             {
78                 case IDOK:
79                     if (CheckPasswords(hwndDlg, IDC_EDIT_PASSWORD1, IDC_EDIT_PASSWORD2))
80                     {
81                         /* Store the password */
82                         userInfo->usri1003_password =
83                             GetDlgItemTextAlloc(hwndDlg, IDC_EDIT_PASSWORD1);
84 
85                         EndDialog(hwndDlg, IDOK);
86                     }
87                     break;
88 
89                 case IDCANCEL:
90                     EndDialog(hwndDlg, IDCANCEL);
91                     break;
92             }
93             break;
94 
95         default:
96             return FALSE;
97     }
98 
99     return TRUE;
100 }
101 
102 
103 static VOID
UserChangePassword(HWND hwndDlg)104 UserChangePassword(HWND hwndDlg)
105 {
106     TCHAR szUserName[UNLEN + 1];
107     USER_INFO_1003 user;
108     INT nItem;
109     HWND hwndLV;
110     NET_API_STATUS status;
111 
112     ZeroMemory(&user, sizeof(USER_INFO_1003));
113 
114     hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
115     nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
116     if (nItem == -1)
117         return;
118 
119     /* Get the new user name */
120     ListView_GetItemText(hwndLV,
121                          nItem, 0,
122                          szUserName,
123                          UNLEN + 1);
124 
125     if (DialogBoxParam(hApplet,
126                        MAKEINTRESOURCE(IDD_CHANGE_PASSWORD),
127                        hwndDlg,
128                        ChangePasswordDlgProc,
129                        (LPARAM)&user) == IDOK)
130     {
131         status = NetUserSetInfo(NULL,
132                                 szUserName,
133                                 1003,
134                                 (LPBYTE)&user,
135                                 NULL);
136         if (status != NERR_Success)
137         {
138             TCHAR szText[256];
139             wsprintf(szText, TEXT("Error: %u"), status);
140             MessageBox(NULL, szText, TEXT("NetUserSetInfo"), MB_ICONERROR | MB_OK);
141         }
142     }
143 
144     HeapFree(GetProcessHeap(), 0, user.usri1003_password);
145 }
146 
147 
148 static VOID
UpdateNewUserOptions(HWND hwndDlg,PUSER_INFO_3 userInfo,BOOL bInit)149 UpdateNewUserOptions(HWND hwndDlg,
150                      PUSER_INFO_3 userInfo,
151                      BOOL bInit)
152 {
153     EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_CANNOT_CHANGE),
154                  !userInfo->usri3_password_expired);
155     EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_NEVER_EXPIRES),
156                  !userInfo->usri3_password_expired);
157 
158     EnableWindow(GetDlgItem(hwndDlg, IDC_USER_NEW_FORCE_CHANGE),
159                  (userInfo->usri3_flags & (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD)) == 0);
160 
161     if (bInit)
162     {
163         CheckDlgButton(hwndDlg, IDC_USER_NEW_FORCE_CHANGE,
164                        userInfo->usri3_password_expired ? BST_CHECKED : BST_UNCHECKED);
165 
166         CheckDlgButton(hwndDlg, IDC_USER_NEW_CANNOT_CHANGE,
167                        (userInfo->usri3_flags & UF_PASSWD_CANT_CHANGE) ? BST_CHECKED : BST_UNCHECKED);
168 
169         CheckDlgButton(hwndDlg, IDC_USER_NEW_NEVER_EXPIRES,
170                        (userInfo->usri3_flags & UF_DONT_EXPIRE_PASSWD) ? BST_CHECKED : BST_UNCHECKED);
171 
172         CheckDlgButton(hwndDlg, IDC_USER_NEW_DISABLED,
173                        (userInfo->usri3_flags & UF_ACCOUNTDISABLE) ? BST_CHECKED : BST_UNCHECKED);
174     }
175 }
176 
177 
178 INT_PTR CALLBACK
NewUserDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)179 NewUserDlgProc(HWND hwndDlg,
180                UINT uMsg,
181                WPARAM wParam,
182                LPARAM lParam)
183 {
184     PUSER_INFO_3 userInfo;
185     INT nLength;
186 
187     UNREFERENCED_PARAMETER(wParam);
188 
189     userInfo = (PUSER_INFO_3)GetWindowLongPtr(hwndDlg, DWLP_USER);
190 
191     switch (uMsg)
192     {
193         case WM_INITDIALOG:
194             userInfo = (PUSER_INFO_3)lParam;
195             SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
196             SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, EM_SETLIMITTEXT, 20, 0);
197             UpdateNewUserOptions(hwndDlg, userInfo, TRUE);
198             break;
199 
200         case WM_COMMAND:
201             switch (LOWORD(wParam))
202             {
203                 case IDC_USER_NEW_NAME:
204                     if (HIWORD(wParam) == EN_CHANGE)
205                     {
206                         nLength = SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, WM_GETTEXTLENGTH, 0, 0);
207                         EnableWindow(GetDlgItem(hwndDlg, IDOK), (nLength > 0));
208                     }
209                     break;
210 
211                 case IDC_USER_NEW_FORCE_CHANGE:
212                     userInfo->usri3_password_expired = !userInfo->usri3_password_expired;
213                     UpdateNewUserOptions(hwndDlg, userInfo, FALSE);
214                     break;
215 
216                 case IDC_USER_NEW_CANNOT_CHANGE:
217                     userInfo->usri3_flags ^= UF_PASSWD_CANT_CHANGE;
218                     UpdateNewUserOptions(hwndDlg, userInfo, FALSE);
219                     break;
220 
221                 case IDC_USER_NEW_NEVER_EXPIRES:
222                     userInfo->usri3_flags ^= UF_DONT_EXPIRE_PASSWD;
223                     UpdateNewUserOptions(hwndDlg, userInfo, FALSE);
224                     break;
225 
226                 case IDC_USER_NEW_DISABLED:
227                     userInfo->usri3_flags ^= UF_ACCOUNTDISABLE;
228                     break;
229 
230                 case IDOK:
231                     if (!CheckAccountName(hwndDlg, IDC_USER_NEW_NAME, NULL))
232                     {
233                         SetFocus(GetDlgItem(hwndDlg, IDC_USER_NEW_NAME));
234                         SendDlgItemMessage(hwndDlg, IDC_USER_NEW_NAME, EM_SETSEL, 0, -1);
235                         break;
236                     }
237 
238                     if (!CheckPasswords(hwndDlg, IDC_USER_NEW_PASSWORD1, IDC_USER_NEW_PASSWORD2))
239                     {
240                         SetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD1, TEXT(""));
241                         SetDlgItemText(hwndDlg, IDC_USER_NEW_PASSWORD2, TEXT(""));
242                         break;
243                     }
244 
245                     /* Store the user name */
246                     userInfo->usri3_name = GetDlgItemTextAlloc(hwndDlg, IDC_USER_NEW_NAME);
247 
248                     /* Store the full user name */
249                     userInfo->usri3_full_name = GetDlgItemTextAlloc(hwndDlg, IDC_USER_NEW_FULL_NAME);
250 
251                     /* Store the description */
252                     userInfo->usri3_comment = GetDlgItemTextAlloc(hwndDlg, IDC_USER_NEW_DESCRIPTION);
253 
254                     /* Store the password */
255                     userInfo->usri3_password = GetDlgItemTextAlloc(hwndDlg, IDC_USER_NEW_PASSWORD1);
256 
257                     EndDialog(hwndDlg, IDOK);
258                     break;
259 
260                 case IDCANCEL:
261                     EndDialog(hwndDlg, IDCANCEL);
262                     break;
263             }
264             break;
265 
266         default:
267             return FALSE;
268     }
269 
270     return TRUE;
271 }
272 
273 
274 static VOID
UserNew(HWND hwndDlg)275 UserNew(HWND hwndDlg)
276 {
277     USER_INFO_3 user;
278     NET_API_STATUS status;
279     LV_ITEM lvi;
280     INT iItem;
281     HWND hwndLV;
282 
283     ZeroMemory(&user, sizeof(USER_INFO_3));
284 
285     user.usri3_priv = USER_PRIV_USER;
286     user.usri3_flags = UF_SCRIPT;
287     user.usri3_acct_expires = TIMEQ_FOREVER;
288     user.usri3_max_storage = USER_MAXSTORAGE_UNLIMITED;
289     user.usri3_primary_group_id = DOMAIN_GROUP_RID_USERS;
290 
291     user.usri3_password_expired = TRUE;
292 
293     if (DialogBoxParam(hApplet,
294                        MAKEINTRESOURCE(IDD_USER_NEW),
295                        hwndDlg,
296                        NewUserDlgProc,
297                        (LPARAM)&user) == IDOK)
298     {
299         status = NetUserAdd(NULL,
300                             3,
301                             (LPBYTE)&user,
302                             NULL);
303         if (status != NERR_Success)
304         {
305             TCHAR szText[256];
306             wsprintf(szText, TEXT("Error: %u"), status);
307             MessageBox(NULL, szText, TEXT("NetUserAdd"), MB_ICONERROR | MB_OK);
308             return;
309         }
310 
311         hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
312 
313         ZeroMemory(&lvi, sizeof(lvi));
314         lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
315         lvi.pszText = user.usri3_name;
316         lvi.state = 0;
317         lvi.iImage = (user.usri3_flags & UF_ACCOUNTDISABLE) ? 1 : 0;
318         iItem = ListView_InsertItem(hwndLV, &lvi);
319 
320         ListView_SetItemText(hwndLV, iItem, 1,
321                              user.usri3_full_name);
322 
323         ListView_SetItemText(hwndLV, iItem, 2,
324                              user.usri3_comment);
325     }
326 
327     HeapFree(GetProcessHeap(), 0, user.usri3_name);
328     HeapFree(GetProcessHeap(), 0, user.usri3_full_name);
329     HeapFree(GetProcessHeap(), 0, user.usri3_comment);
330     HeapFree(GetProcessHeap(), 0, user.usri3_password);
331 }
332 
333 
334 static VOID
UserRename(HWND hwndDlg)335 UserRename(HWND hwndDlg)
336 {
337     HWND hwndLV;
338     INT nItem;
339 
340     hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
341     if (hwndLV == NULL)
342         return;
343 
344     nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
345     if (nItem != -1)
346     {
347         (void)ListView_EditLabel(hwndLV, nItem);
348     }
349 }
350 
351 
352 static BOOL
UserDelete(HWND hwndDlg)353 UserDelete(HWND hwndDlg)
354 {
355     TCHAR szUserName[UNLEN + 1];
356     TCHAR szText[256];
357     INT nItem;
358     HWND hwndLV;
359     NET_API_STATUS status;
360 
361     hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
362     nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
363     if (nItem == -1)
364         return FALSE;
365 
366     /* Get the new user name */
367     ListView_GetItemText(hwndLV,
368                          nItem, 0,
369                          szUserName,
370                          UNLEN + 1);
371 
372     /* Display a warning message because the delete operation cannot be reverted */
373     wsprintf(szText, TEXT("Do you really want to delete the user \"%s\"?"), szUserName);
374     if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO)
375         return FALSE;
376 
377     /* Delete the user */
378     status = NetUserDel(NULL, szUserName);
379     if (status != NERR_Success)
380     {
381         TCHAR szText[256];
382         wsprintf(szText, TEXT("Error: %u"), status);
383         MessageBox(NULL, szText, TEXT("NetUserDel"), MB_ICONERROR | MB_OK);
384         return FALSE;
385     }
386 
387     /* Delete the user from the list */
388     (void)ListView_DeleteItem(hwndLV, nItem);
389 
390     return TRUE;
391 }
392 
393 
394 static VOID
SetUsersListColumns(HWND hwndListView)395 SetUsersListColumns(HWND hwndListView)
396 {
397     LV_COLUMN column;
398     RECT rect;
399     TCHAR szStr[32];
400 
401     GetClientRect(hwndListView, &rect);
402 
403     memset(&column, 0x00, sizeof(column));
404     column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
405     column.fmt=LVCFMT_LEFT;
406     column.cx = (INT)((rect.right - rect.left) * 0.25);
407     column.iSubItem = 0;
408     LoadString(hApplet, IDS_NAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
409     column.pszText = szStr;
410     (void)ListView_InsertColumn(hwndListView, 0, &column);
411 
412     column.cx = (INT)((rect.right - rect.left) * 0.50);
413     column.iSubItem = 1;
414     LoadString(hApplet, IDS_FULLNAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
415     column.pszText = szStr;
416     (void)ListView_InsertColumn(hwndListView, 1, &column);
417 
418     column.cx = (INT)((rect.right - rect.left) * 0.25);
419     column.iSubItem = 2;
420     LoadString(hApplet, IDS_DESCRIPTION, szStr, sizeof(szStr) / sizeof(szStr[0]));
421     column.pszText = szStr;
422     (void)ListView_InsertColumn(hwndListView, 2, &column);
423 }
424 
425 
426 static VOID
UpdateUsersList(HWND hwndListView)427 UpdateUsersList(HWND hwndListView)
428 {
429     NET_API_STATUS netStatus;
430     PUSER_INFO_20 pBuffer;
431     DWORD entriesread;
432     DWORD totalentries;
433     DWORD resume_handle = 0;
434     DWORD i;
435     LV_ITEM lvi;
436     INT iItem;
437 
438     for (;;)
439     {
440         netStatus = NetUserEnum(NULL, 20, FILTER_NORMAL_ACCOUNT,
441                                 (LPBYTE*)&pBuffer,
442                                 1024, &entriesread,
443                                 &totalentries, &resume_handle);
444         if (netStatus != NERR_Success && netStatus != ERROR_MORE_DATA)
445             break;
446 
447         for (i = 0; i < entriesread; i++)
448         {
449            memset(&lvi, 0x00, sizeof(lvi));
450            lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
451            lvi.pszText = pBuffer[i].usri20_name;
452            lvi.state = 0;
453            lvi.iImage = (pBuffer[i].usri20_flags & UF_ACCOUNTDISABLE) ? 1 : 0;
454            iItem = ListView_InsertItem(hwndListView, &lvi);
455 
456            if (pBuffer[i].usri20_full_name != NULL)
457                ListView_SetItemText(hwndListView, iItem, 1,
458                                     pBuffer[i].usri20_full_name);
459 
460            if (pBuffer[i].usri20_comment != NULL)
461                ListView_SetItemText(hwndListView, iItem, 2,
462                                     pBuffer[i].usri20_comment);
463         }
464 
465         NetApiBufferFree(pBuffer);
466 
467         /* No more data left */
468         if (netStatus != ERROR_MORE_DATA)
469             break;
470     }
471 }
472 
473 
474 static VOID
OnInitDialog(HWND hwndDlg)475 OnInitDialog(HWND hwndDlg)
476 {
477     HWND hwndListView;
478     HIMAGELIST hImgList;
479     HICON hIcon;
480 
481     /* Create the image list */
482     hImgList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 5, 5);
483     hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
484     ImageList_AddIcon(hImgList, hIcon);
485     hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOCKED_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
486     ImageList_AddIcon(hImgList, hIcon);
487     DestroyIcon(hIcon);
488 
489     hwndListView = GetDlgItem(hwndDlg, IDC_USERS_LIST);
490 
491     (VOID)ListView_SetImageList(hwndListView, hImgList, LVSIL_SMALL);
492 
493     (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
494 
495     SetUsersListColumns(hwndListView);
496 
497     UpdateUsersList(hwndListView);
498 }
499 
500 
501 static BOOL
OnBeginLabelEdit(LPNMLVDISPINFO pnmv)502 OnBeginLabelEdit(LPNMLVDISPINFO pnmv)
503 {
504     HWND hwndEdit;
505 
506     hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom);
507     if (hwndEdit == NULL)
508         return TRUE;
509 
510     SendMessage(hwndEdit, EM_SETLIMITTEXT, 20, 0);
511 
512     return FALSE;
513 }
514 
515 
516 static BOOL
OnEndLabelEdit(LPNMLVDISPINFO pnmv)517 OnEndLabelEdit(LPNMLVDISPINFO pnmv)
518 {
519     TCHAR szOldUserName[UNLEN + 1];
520     TCHAR szNewUserName[UNLEN + 1];
521     USER_INFO_0 useri0;
522     NET_API_STATUS status;
523 
524     /* Leave, if there is no valid listview item */
525     if (pnmv->item.iItem == -1)
526         return FALSE;
527 
528     /* Get the new user name */
529     ListView_GetItemText(pnmv->hdr.hwndFrom,
530                          pnmv->item.iItem, 0,
531                          szOldUserName,
532                          UNLEN + 1);
533 
534     /* Leave, if the user canceled the edit action */
535     if (pnmv->item.pszText == NULL)
536         return FALSE;
537 
538     /* Get the new user name */
539     lstrcpy(szNewUserName, pnmv->item.pszText);
540 
541     /* Leave, if the user name was not changed */
542     if (lstrcmp(szOldUserName, szNewUserName) == 0)
543         return FALSE;
544 
545     /* Check the user name for illegal characters */
546     if (!CheckAccountName(NULL, 0, szNewUserName))
547         return FALSE;
548 
549     /* Change the user name */
550     useri0.usri0_name = szNewUserName;
551 
552     status = NetUserSetInfo(NULL, szOldUserName, 0, (LPBYTE)&useri0, NULL);
553     if (status != NERR_Success)
554     {
555         TCHAR szText[256];
556         wsprintf(szText, TEXT("Error: %u"), status);
557         MessageBox(NULL, szText, TEXT("NetUserSetInfo"), MB_ICONERROR | MB_OK);
558         return FALSE;
559     }
560 
561     /* Update the listview item */
562     ListView_SetItemText(pnmv->hdr.hwndFrom,
563                          pnmv->item.iItem, 0,
564                          szNewUserName);
565 
566     return TRUE;
567 }
568 
569 
570 static BOOL
OnNotify(HWND hwndDlg,PUSER_DATA pUserData,NMHDR * phdr)571 OnNotify(HWND hwndDlg, PUSER_DATA pUserData, NMHDR *phdr)
572 {
573     LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
574 
575     switch (phdr->idFrom)
576     {
577         case IDC_USERS_LIST:
578             switch(phdr->code)
579             {
580                 case NM_CLICK:
581                     pUserData->iCurrentItem = lpnmlv->iItem;
582                     break;
583 
584                 case NM_DBLCLK:
585                     if (lpnmlv->iItem != -1)
586                     {
587                         UINT uItem;
588 
589                         uItem =  GetMenuDefaultItem(GetSubMenu(pUserData->hPopupMenu, 1),
590                                                     FALSE, 0);
591                         if (uItem != (UINT)-1)
592                             SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(uItem, 0), 0);
593                     }
594                     break;
595 
596                 case NM_RCLICK:
597                     ClientToScreen(GetDlgItem(hwndDlg, IDC_USERS_LIST), &lpnmlv->ptAction);
598                     TrackPopupMenu(GetSubMenu(pUserData->hPopupMenu, (lpnmlv->iItem == -1) ? 0 : 1),
599                                    TPM_LEFTALIGN, lpnmlv->ptAction.x, lpnmlv->ptAction.y, 0, hwndDlg, NULL);
600                     break;
601 
602                 case LVN_BEGINLABELEDIT:
603                     return OnBeginLabelEdit((LPNMLVDISPINFO)phdr);
604 
605                 case LVN_ENDLABELEDIT:
606                     return OnEndLabelEdit((LPNMLVDISPINFO)phdr);
607             }
608             break;
609     }
610 
611     return FALSE;
612 }
613 
614 
615 static VOID
UpdateUserProperties(HWND hwndDlg)616 UpdateUserProperties(HWND hwndDlg)
617 {
618     TCHAR szUserName[UNLEN + 1];
619     INT iItem;
620     HWND hwndLV;
621     PUSER_INFO_2 pUserInfo = NULL;
622     LV_ITEM lvi;
623 
624     hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
625     iItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
626     if (iItem == -1)
627         return;
628 
629     /* Get the new user name */
630     ListView_GetItemText(hwndLV,
631                          iItem, 0,
632                          szUserName,
633                          UNLEN + 1);
634 
635     NetUserGetInfo(NULL, szUserName, 2, (LPBYTE*)&pUserInfo);
636 
637     memset(&lvi, 0x00, sizeof(lvi));
638     lvi.iItem = iItem;
639     lvi.iSubItem = 0;
640     lvi.mask = LVIF_IMAGE;
641     lvi.iImage = (pUserInfo->usri2_flags & UF_ACCOUNTDISABLE) ? 1 : 0;
642     (void)ListView_SetItem(hwndLV, &lvi);
643 
644     ListView_SetItemText(hwndLV, iItem, 1,
645                          pUserInfo->usri2_full_name);
646 
647     ListView_SetItemText(hwndLV, iItem, 2,
648                          pUserInfo->usri2_comment);
649 
650     NetApiBufferFree(pUserInfo);
651 }
652 
653 
654 INT_PTR CALLBACK
UsersPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)655 UsersPageProc(HWND hwndDlg,
656               UINT uMsg,
657               WPARAM wParam,
658               LPARAM lParam)
659 {
660     PUSER_DATA pUserData;
661 
662     UNREFERENCED_PARAMETER(wParam);
663 
664     pUserData = (PUSER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
665 
666     switch (uMsg)
667     {
668         case WM_INITDIALOG:
669             pUserData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(USER_DATA));
670             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pUserData);
671 
672             pUserData->hPopupMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDM_POPUP_USER));
673 
674             OnInitDialog(hwndDlg);
675             SetMenuDefaultItem(GetSubMenu(pUserData->hPopupMenu, 1),
676                                IDM_USER_PROPERTIES,
677                                FALSE);
678             break;
679 
680         case WM_COMMAND:
681             switch (LOWORD(wParam))
682             {
683                 case IDM_USER_CHANGE_PASSWORD:
684                     UserChangePassword(hwndDlg);
685                     break;
686 
687                 case IDM_USER_RENAME:
688                     UserRename(hwndDlg);
689                     break;
690 
691                 case IDM_USER_NEW:
692                 case IDC_USERS_ADD:
693                     UserNew(hwndDlg);
694                     break;
695 
696                 case IDM_USER_DELETE:
697                 case IDC_USERS_REMOVE:
698                     UserDelete(hwndDlg);
699                     break;
700 
701                 case IDM_USER_PROPERTIES:
702                 case IDC_USERS_PROPERTIES:
703                     if (UserProperties(hwndDlg))
704                     {
705                         UpdateUserProperties(hwndDlg);
706                     }
707                     break;
708             }
709             break;
710 
711         case WM_NOTIFY:
712             return OnNotify(hwndDlg, pUserData, (NMHDR *)lParam);
713 
714         case WM_DESTROY:
715             DestroyMenu(pUserData->hPopupMenu);
716             HeapFree(GetProcessHeap(), 0, pUserData);
717             break;
718     }
719 
720     return FALSE;
721 }
722