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