97b582e1d5bb64d3cbc08ce066e6b67ccf284ce6
[reactos.git] / reactos / dll / cpl / usrmgr / users.c
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 status = NetUserAdd(NULL,
265 3,
266 (LPBYTE)&user,
267 NULL);
268 if (status != NERR_Success)
269 {
270 TCHAR szText[256];
271 wsprintf(szText, TEXT("Error: %u"), status);
272 MessageBox(NULL, szText, TEXT("NetUserAdd"), MB_ICONERROR | MB_OK);
273 return;
274 }
275
276 hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
277
278 ZeroMemory(&lvi, sizeof(lvi));
279 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
280 lvi.pszText = user.usri3_name;
281 lvi.state = 0;
282 lvi.iImage = (user.usri3_flags & UF_ACCOUNTDISABLE) ? 1 : 0;
283 iItem = ListView_InsertItem(hwndLV, &lvi);
284
285 ListView_SetItemText(hwndLV, iItem, 1,
286 user.usri3_full_name);
287
288 ListView_SetItemText(hwndLV, iItem, 2,
289 user.usri3_comment);
290 }
291
292 if (user.usri3_name)
293 HeapFree(GetProcessHeap(), 0, user.usri3_name);
294
295 if (user.usri3_full_name)
296 HeapFree(GetProcessHeap(), 0, user.usri3_full_name);
297
298 if (user.usri3_comment)
299 HeapFree(GetProcessHeap(), 0, user.usri3_comment);
300
301 if (user.usri3_password)
302 HeapFree(GetProcessHeap(), 0, user.usri3_password);
303 }
304
305
306 static VOID
307 UserRename(HWND hwndDlg)
308 {
309 HWND hwndLV;
310 INT nItem;
311
312 hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
313 if (hwndLV == NULL)
314 return;
315
316 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
317 if (nItem != -1)
318 {
319 (void)ListView_EditLabel(hwndLV, nItem);
320 }
321 }
322
323
324 static BOOL
325 UserDelete(HWND hwndDlg)
326 {
327 TCHAR szUserName[UNLEN];
328 TCHAR szText[256];
329 INT nItem;
330 HWND hwndLV;
331 NET_API_STATUS status;
332
333 hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
334 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
335 if (nItem == -1)
336 return FALSE;
337
338 /* Get the new user name */
339 ListView_GetItemText(hwndLV,
340 nItem, 0,
341 szUserName,
342 UNLEN);
343
344 /* Display a warning message because the delete operation cannot be reverted */
345 wsprintf(szText, TEXT("Do you really want to delete the user \"%s\"?"), szUserName);
346 if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO)
347 return FALSE;
348
349 /* Delete the user */
350 status = NetUserDel(NULL, szUserName);
351 if (status != NERR_Success)
352 {
353 TCHAR szText[256];
354 wsprintf(szText, TEXT("Error: %u"), status);
355 MessageBox(NULL, szText, TEXT("NetUserDel"), MB_ICONERROR | MB_OK);
356 return FALSE;
357 }
358
359 /* Delete the user from the list */
360 (void)ListView_DeleteItem(hwndLV, nItem);
361
362 return TRUE;
363 }
364
365
366 static VOID
367 SetUsersListColumns(HWND hwndListView)
368 {
369 LV_COLUMN column;
370 RECT rect;
371 TCHAR szStr[32];
372
373 GetClientRect(hwndListView, &rect);
374
375 memset(&column, 0x00, sizeof(column));
376 column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
377 column.fmt=LVCFMT_LEFT;
378 column.cx = (INT)((rect.right - rect.left) * 0.25);
379 column.iSubItem = 0;
380 LoadString(hApplet, IDS_NAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
381 column.pszText = szStr;
382 (void)ListView_InsertColumn(hwndListView, 0, &column);
383
384 column.cx = (INT)((rect.right - rect.left) * 0.50);
385 column.iSubItem = 1;
386 LoadString(hApplet, IDS_FULLNAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
387 column.pszText = szStr;
388 (void)ListView_InsertColumn(hwndListView, 1, &column);
389
390 column.cx = (INT)((rect.right - rect.left) * 0.25);
391 column.iSubItem = 2;
392 LoadString(hApplet, IDS_DESCRIPTION, szStr, sizeof(szStr) / sizeof(szStr[0]));
393 column.pszText = szStr;
394 (void)ListView_InsertColumn(hwndListView, 2, &column);
395 }
396
397
398 static VOID
399 UpdateUsersList(HWND hwndListView)
400 {
401 NET_API_STATUS netStatus;
402 PUSER_INFO_20 pBuffer;
403 DWORD entriesread;
404 DWORD totalentries;
405 DWORD resume_handle = 0;
406 DWORD i;
407 LV_ITEM lvi;
408 INT iItem;
409
410
411 for (;;)
412 {
413 netStatus = NetUserEnum(NULL, 20, FILTER_NORMAL_ACCOUNT,
414 (LPBYTE*)&pBuffer,
415 1024, &entriesread,
416 &totalentries, &resume_handle);
417 if (netStatus != NERR_Success && netStatus != ERROR_MORE_DATA)
418 break;
419
420 for (i = 0; i < entriesread; i++)
421 {
422 memset(&lvi, 0x00, sizeof(lvi));
423 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
424 lvi.pszText = pBuffer[i].usri20_name;
425 lvi.state = 0;
426 lvi.iImage = (pBuffer[i].usri20_flags & UF_ACCOUNTDISABLE) ? 1 : 0;
427 iItem = ListView_InsertItem(hwndListView, &lvi);
428
429 if (pBuffer[i].usri20_full_name != NULL)
430 ListView_SetItemText(hwndListView, iItem, 1,
431 pBuffer[i].usri20_full_name);
432
433 if (pBuffer[i].usri20_comment != NULL)
434 ListView_SetItemText(hwndListView, iItem, 2,
435 pBuffer[i].usri20_comment);
436 }
437
438 NetApiBufferFree(pBuffer);
439
440 /* No more data left */
441 if (netStatus != ERROR_MORE_DATA)
442 break;
443 }
444
445 }
446
447
448 static VOID
449 OnInitDialog(HWND hwndDlg)
450 {
451 HWND hwndListView;
452 HIMAGELIST hImgList;
453 HICON hIcon;
454
455 /* Create the image list */
456 hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 5, 5);
457 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
458 ImageList_AddIcon(hImgList, hIcon);
459 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOCKED_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
460 ImageList_AddIcon(hImgList, hIcon);
461 DestroyIcon(hIcon);
462
463 hwndListView = GetDlgItem(hwndDlg, IDC_USERS_LIST);
464
465 (VOID)ListView_SetImageList(hwndListView, hImgList, LVSIL_SMALL);
466
467 (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
468
469 SetUsersListColumns(hwndListView);
470
471 UpdateUsersList(hwndListView);
472 }
473
474
475 static BOOL
476 OnBeginLabelEdit(LPNMLVDISPINFO pnmv)
477 {
478 HWND hwndEdit;
479
480 hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom);
481 if (hwndEdit == NULL)
482 return TRUE;
483
484 SendMessage(hwndEdit, EM_SETLIMITTEXT, 20, 0);
485
486 return FALSE;
487 }
488
489
490 static BOOL
491 OnEndLabelEdit(LPNMLVDISPINFO pnmv)
492 {
493 TCHAR szOldUserName[UNLEN];
494 TCHAR szNewUserName[UNLEN];
495 USER_INFO_0 useri0;
496 NET_API_STATUS status;
497
498 /* Leave, if there is no valid listview item */
499 if (pnmv->item.iItem == -1)
500 return FALSE;
501
502 /* Get the new user name */
503 ListView_GetItemText(pnmv->hdr.hwndFrom,
504 pnmv->item.iItem, 0,
505 szOldUserName,
506 UNLEN);
507
508 /* Leave, if the user canceled the edit action */
509 if (pnmv->item.pszText == NULL)
510 return FALSE;
511
512 /* Get the new user name */
513 lstrcpy(szNewUserName, pnmv->item.pszText);
514
515 /* Leave, if the user name was not changed */
516 if (lstrcmp(szOldUserName, szNewUserName) == 0)
517 return FALSE;
518
519 /* Check the user name for illegal characters */
520 if (!CheckAccountName(NULL, 0, szNewUserName))
521 return FALSE;
522
523 /* Change the user name */
524 useri0.usri0_name = szNewUserName;
525
526 status = NetUserSetInfo(NULL, szOldUserName, 0, (LPBYTE)&useri0, NULL);
527 if (status != NERR_Success)
528 {
529 TCHAR szText[256];
530 wsprintf(szText, TEXT("Error: %u"), status);
531 MessageBox(NULL, szText, TEXT("NetUserSetInfo"), MB_ICONERROR | MB_OK);
532 return FALSE;
533 }
534
535 /* Update the listview item */
536 ListView_SetItemText(pnmv->hdr.hwndFrom,
537 pnmv->item.iItem, 0,
538 szNewUserName);
539
540 return TRUE;
541 }
542
543
544 static BOOL
545 OnNotify(HWND hwndDlg, PUSER_DATA pUserData, NMHDR *phdr)
546 {
547 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
548
549 switch (phdr->idFrom)
550 {
551 case IDC_USERS_LIST:
552 switch(phdr->code)
553 {
554 case NM_CLICK:
555 pUserData->iCurrentItem = lpnmlv->iItem;
556 break;
557
558 case NM_DBLCLK:
559 if (lpnmlv->iItem != -1)
560 {
561 UINT uItem;
562
563 uItem = GetMenuDefaultItem(GetSubMenu(pUserData->hPopupMenu, 1),
564 FALSE, 0);
565 if (uItem != (UINT)-1)
566 SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(uItem, 0), 0);
567 }
568 break;
569
570 case NM_RCLICK:
571 ClientToScreen(GetDlgItem(hwndDlg, IDC_USERS_LIST), &lpnmlv->ptAction);
572 TrackPopupMenu(GetSubMenu(pUserData->hPopupMenu, (lpnmlv->iItem == -1) ? 0 : 1),
573 TPM_LEFTALIGN, lpnmlv->ptAction.x, lpnmlv->ptAction.y, 0, hwndDlg, NULL);
574 break;
575
576 case LVN_BEGINLABELEDIT:
577 return OnBeginLabelEdit((LPNMLVDISPINFO)phdr);
578
579 case LVN_ENDLABELEDIT:
580 return OnEndLabelEdit((LPNMLVDISPINFO)phdr);
581 }
582 break;
583 }
584
585 return FALSE;
586 }
587
588
589 static VOID
590 UpdateUserProperties(HWND hwndDlg)
591 {
592 TCHAR szUserName[UNLEN];
593 INT iItem;
594 HWND hwndLV;
595 PUSER_INFO_2 pUserInfo = NULL;
596 LV_ITEM lvi;
597
598 hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
599 iItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
600 if (iItem == -1)
601 return;
602
603 /* Get the new user name */
604 ListView_GetItemText(hwndLV,
605 iItem, 0,
606 szUserName,
607 UNLEN);
608
609 NetUserGetInfo(NULL, szUserName, 2, (LPBYTE*)&pUserInfo);
610
611 memset(&lvi, 0x00, sizeof(lvi));
612 lvi.iItem = iItem;
613 lvi.iSubItem = 0;
614 lvi.mask = LVIF_IMAGE;
615 lvi.iImage = (pUserInfo->usri2_flags & UF_ACCOUNTDISABLE) ? 1 : 0;
616 (void)ListView_SetItem(hwndLV, &lvi);
617
618 ListView_SetItemText(hwndLV, iItem, 1,
619 pUserInfo->usri2_full_name);
620
621 ListView_SetItemText(hwndLV, iItem, 2,
622 pUserInfo->usri2_comment);
623
624 NetApiBufferFree(pUserInfo);
625 }
626
627
628 INT_PTR CALLBACK
629 UsersPageProc(HWND hwndDlg,
630 UINT uMsg,
631 WPARAM wParam,
632 LPARAM lParam)
633 {
634 PUSER_DATA pUserData;
635
636 UNREFERENCED_PARAMETER(wParam);
637
638 pUserData = (PUSER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
639
640 switch (uMsg)
641 {
642 case WM_INITDIALOG:
643 pUserData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(USER_DATA));
644 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pUserData);
645
646 pUserData->hPopupMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDM_POPUP_USER));
647
648 OnInitDialog(hwndDlg);
649 SetMenuDefaultItem(GetSubMenu(pUserData->hPopupMenu, 1),
650 IDM_USER_PROPERTIES,
651 FALSE);
652 break;
653
654 case WM_COMMAND:
655 switch (LOWORD(wParam))
656 {
657 case IDM_USER_CHANGE_PASSWORD:
658 DialogBoxParam(hApplet,
659 MAKEINTRESOURCE(IDD_CHANGE_PASSWORD),
660 hwndDlg,
661 ChangePasswordDlgProc,
662 (LPARAM)NULL);
663 break;
664
665 case IDM_USER_RENAME:
666 UserRename(hwndDlg);
667 break;
668
669 case IDM_USER_NEW:
670 case IDC_USERS_ADD:
671 UserNew(hwndDlg);
672 break;
673
674 case IDM_USER_DELETE:
675 case IDC_USERS_REMOVE:
676 UserDelete(hwndDlg);
677 break;
678
679 case IDM_USER_PROPERTIES:
680 case IDC_USERS_PROPERTIES:
681 if (UserProperties(hwndDlg))
682 {
683 UpdateUserProperties(hwndDlg);
684 }
685 break;
686 }
687 break;
688
689 case WM_NOTIFY:
690 return OnNotify(hwndDlg, pUserData, (NMHDR *)lParam);
691
692 case WM_DESTROY:
693 DestroyMenu(pUserData->hPopupMenu);
694 HeapFree(GetProcessHeap(), 0, pUserData);
695 break;
696 }
697
698 return FALSE;
699 }