xref: /reactos/dll/cpl/usrmgr/groups.c (revision 29fa274d)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS User Manager Control Panel
4  * FILE:            dll/cpl/usrmgr/groups.c
5  * PURPOSE:         Groups property page
6  *
7  * PROGRAMMERS:     Eric Kohl
8  */
9 
10 #include "usrmgr.h"
11 
12 typedef struct _GROUP_DATA
13 {
14     HMENU hPopupMenu;
15 
16     INT iCurrentItem;
17 
18 } GROUP_DATA, *PGROUP_DATA;
19 
20 
21 static VOID
22 SetGroupsListColumns(HWND hwndListView)
23 {
24     LV_COLUMN column;
25     RECT rect;
26     TCHAR szStr[32];
27 
28     GetClientRect(hwndListView, &rect);
29 
30     memset(&column, 0x00, sizeof(column));
31     column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
32     column.fmt = LVCFMT_LEFT;
33     column.cx = (INT)((rect.right - rect.left) * 0.40);
34     column.iSubItem = 0;
35     LoadString(hApplet, IDS_NAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
36     column.pszText = szStr;
37     (void)ListView_InsertColumn(hwndListView, 0, &column);
38 
39     column.cx = (INT)((rect.right - rect.left) * 0.60);
40     column.iSubItem = 1;
41     LoadString(hApplet, IDS_DESCRIPTION, szStr, sizeof(szStr) / sizeof(szStr[0]));
42     column.pszText = szStr;
43     (void)ListView_InsertColumn(hwndListView, 1, &column);
44 }
45 
46 
47 static VOID
48 UpdateGroupsList(HWND hwndListView)
49 {
50     NET_API_STATUS netStatus;
51     PLOCALGROUP_INFO_1 pBuffer;
52     DWORD entriesread;
53     DWORD totalentries;
54     DWORD resume_handle = 0;
55     DWORD i;
56     LV_ITEM lvi;
57     INT iItem;
58 
59     for (;;)
60     {
61         netStatus = NetLocalGroupEnum(NULL, 1, (LPBYTE*)&pBuffer,
62                                       1024, &entriesread,
63                                       &totalentries, &resume_handle);
64         if (netStatus != NERR_Success && netStatus != ERROR_MORE_DATA)
65             break;
66 
67         for (i = 0; i < entriesread; i++)
68         {
69            memset(&lvi, 0x00, sizeof(lvi));
70            lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
71            lvi.pszText = pBuffer[i].lgrpi1_name;
72            lvi.state = 0;
73            lvi.iImage = 0;
74            iItem = ListView_InsertItem(hwndListView, &lvi);
75 
76            ListView_SetItemText(hwndListView, iItem, 1,
77                                 pBuffer[i].lgrpi1_comment);
78         }
79 
80         NetApiBufferFree(&pBuffer);
81 
82         /* No more data left */
83         if (netStatus != ERROR_MORE_DATA)
84             break;
85     }
86 
87 }
88 
89 
90 static VOID
91 UpdateGroupProperties(HWND hwndDlg)
92 {
93     TCHAR szGroupName[UNLEN];
94     INT iItem;
95     HWND hwndLV;
96     NET_API_STATUS status;
97     PLOCALGROUP_INFO_1 pGroupInfo = NULL;
98 
99     hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
100     iItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
101     if (iItem == -1)
102         return;
103 
104     /* Get the group name */
105     ListView_GetItemText(hwndLV,
106                          iItem, 0,
107                          szGroupName,
108                          UNLEN);
109 
110     status = NetLocalGroupGetInfo(NULL, szGroupName, 1, (LPBYTE*)&pGroupInfo);
111 
112     ListView_SetItemText(hwndLV, iItem, 1,
113                          pGroupInfo->lgrpi1_comment);
114 
115     NetApiBufferFree(pGroupInfo);
116 }
117 
118 
119 INT_PTR CALLBACK
120 NewGroupDlgProc(HWND hwndDlg,
121                UINT uMsg,
122                WPARAM wParam,
123                LPARAM lParam)
124 {
125     PLOCALGROUP_INFO_1 groupInfo;
126     INT nLength;
127 
128     UNREFERENCED_PARAMETER(wParam);
129 
130     groupInfo = (PLOCALGROUP_INFO_1)GetWindowLongPtr(hwndDlg, DWLP_USER);
131 
132     switch (uMsg)
133     {
134         case WM_INITDIALOG:
135             SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
136             groupInfo = (PLOCALGROUP_INFO_1)lParam;
137             SendDlgItemMessage(hwndDlg, IDC_GROUP_NEW_NAME, EM_SETLIMITTEXT, 20, 0);
138             break;
139 
140         case WM_COMMAND:
141             switch (LOWORD(wParam))
142             {
143                 case IDC_GROUP_NEW_NAME:
144                     if (HIWORD(wParam) == EN_CHANGE)
145                     {
146                         nLength = SendDlgItemMessage(hwndDlg, IDC_GROUP_NEW_NAME, WM_GETTEXTLENGTH, 0, 0);
147                         EnableWindow(GetDlgItem(hwndDlg, IDOK), (nLength > 0));
148                     }
149                     break;
150 
151                 case IDOK:
152                     if (!CheckAccountName(hwndDlg, IDC_GROUP_NEW_NAME, NULL))
153                     {
154                         SetFocus(GetDlgItem(hwndDlg, IDC_GROUP_NEW_NAME));
155                         SendDlgItemMessage(hwndDlg, IDC_GROUP_NEW_NAME, EM_SETSEL, 0, -1);
156                         break;
157                     }
158 
159                     nLength = SendDlgItemMessage(hwndDlg, IDC_GROUP_NEW_NAME, WM_GETTEXTLENGTH, 0, 0);
160                     if (nLength > 0)
161                     {
162                         groupInfo->lgrpi1_name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
163                         GetDlgItemText(hwndDlg, IDC_GROUP_NEW_NAME, groupInfo->lgrpi1_name, nLength + 1);
164                     }
165 
166                     nLength = SendDlgItemMessage(hwndDlg, IDC_GROUP_NEW_DESCRIPTION, WM_GETTEXTLENGTH, 0, 0);
167                     if (nLength > 0)
168                     {
169                         groupInfo->lgrpi1_comment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
170                         GetDlgItemText(hwndDlg, IDC_GROUP_NEW_DESCRIPTION, groupInfo->lgrpi1_comment, nLength + 1);
171                     }
172 
173                     EndDialog(hwndDlg, IDOK);
174                     break;
175 
176                 case IDCANCEL:
177                     EndDialog(hwndDlg, IDCANCEL);
178                     break;
179             }
180             break;
181 
182         default:
183             return FALSE;
184     }
185 
186     return TRUE;
187 }
188 
189 
190 static VOID
191 GroupNew(HWND hwndDlg)
192 {
193     NET_API_STATUS status;
194     LOCALGROUP_INFO_1 group;
195     LV_ITEM lvi;
196     INT iItem;
197     HWND hwndLV;
198 
199     ZeroMemory(&group, sizeof(LOCALGROUP_INFO_1));
200 
201     if (DialogBoxParam(hApplet,
202                        MAKEINTRESOURCE(IDD_GROUP_NEW),
203                        hwndDlg,
204                        NewGroupDlgProc,
205                        (LPARAM)&group) == IDOK)
206     {
207 #if 0
208         status = NetLocalGroupAdd(NULL,
209                                   1,
210                                   (LPBYTE)&group,
211                                   NULL);
212 #else
213         status = NERR_Success;
214 #endif
215         if (status != NERR_Success)
216         {
217             TCHAR szText[256];
218             wsprintf(szText, TEXT("Error: %u"), status);
219             MessageBox(NULL, szText, TEXT("NetUserAdd"), MB_ICONERROR | MB_OK);
220             return;
221         }
222 
223         hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
224 
225         ZeroMemory(&lvi, sizeof(lvi));
226         lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
227         lvi.pszText = group.lgrpi1_name;
228         lvi.state = 0;
229         lvi.iImage = 0;
230         iItem = ListView_InsertItem(hwndLV, &lvi);
231 
232         ListView_SetItemText(hwndLV, iItem, 1,
233                              group.lgrpi1_comment);
234     }
235 
236     if (group.lgrpi1_name)
237         HeapFree(GetProcessHeap, 0, group.lgrpi1_name);
238 
239     if (group.lgrpi1_comment)
240         HeapFree(GetProcessHeap, 0, group.lgrpi1_comment);
241 }
242 
243 
244 static VOID
245 GroupRename(HWND hwndDlg)
246 {
247     INT nItem;
248     HWND hwndLV;
249 
250     hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
251     nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
252     if (nItem != -1)
253     {
254         (void)ListView_EditLabel(hwndLV, nItem);
255     }
256 }
257 
258 
259 static BOOL
260 GroupDelete(HWND hwndDlg)
261 {
262     TCHAR szGroupName[UNLEN];
263     TCHAR szText[256];
264     INT nItem;
265     HWND hwndLV;
266     NET_API_STATUS status;
267 
268     hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
269     nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
270     if (nItem == -1)
271         return FALSE;
272 
273     /* Get the new group name */
274     ListView_GetItemText(hwndLV,
275                          nItem, 0,
276                          szGroupName,
277                          UNLEN);
278 
279     /* Display a warning message because the delete operation cannot be reverted */
280     wsprintf(szText, TEXT("Dou you really want to delete the user group \"%s\"?"), szGroupName);
281     if (MessageBox(NULL, szText, TEXT("User Groups"), MB_ICONWARNING | MB_YESNO) == IDNO)
282         return FALSE;
283 
284     /* Delete the group */
285 #if 0
286     status = NetLocalGroupDel(NULL, szGroupName);
287 #else
288     status = NERR_Success;
289 #endif
290     if (status != NERR_Success)
291     {
292         TCHAR szText[256];
293         wsprintf(szText, TEXT("Error: %u"), status);
294         MessageBox(NULL, szText, TEXT("NetLocalGroupDel"), MB_ICONERROR | MB_OK);
295         return FALSE;
296     }
297 
298     /* Delete the group from the list */
299     (void)ListView_DeleteItem(hwndLV, nItem);
300 
301     return TRUE;
302 }
303 
304 
305 static VOID
306 OnInitDialog(HWND hwndDlg)
307 {
308     HWND hwndListView;
309     HIMAGELIST hImgList;
310     HICON hIcon;
311 
312     /* Create the image list */
313     hImgList = ImageList_Create(16,16,ILC_COLOR8 | ILC_MASK,5,5);
314     hIcon = LoadImage(hApplet,MAKEINTRESOURCE(IDI_GROUP),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
315     ImageList_AddIcon(hImgList,hIcon);
316     DestroyIcon(hIcon);
317 
318     hwndListView = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
319 
320     (VOID)ListView_SetImageList(hwndListView, hImgList, LVSIL_SMALL);
321 
322     (void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
323 
324     SetGroupsListColumns(hwndListView);
325 
326     UpdateGroupsList(hwndListView);
327 }
328 
329 
330 static BOOL
331 OnBeginLabelEdit(LPNMLVDISPINFO pnmv)
332 {
333     HWND hwndEdit;
334 
335     hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom);
336     if (hwndEdit == NULL)
337         return TRUE;
338 
339     SendMessage(hwndEdit, EM_SETLIMITTEXT, 20, 0);
340 
341     return FALSE;
342 }
343 
344 
345 static BOOL
346 OnEndLabelEdit(LPNMLVDISPINFO pnmv)
347 {
348     TCHAR szOldGroupName[UNLEN];
349     TCHAR szNewGroupName[UNLEN];
350     LOCALGROUP_INFO_0 lgrpi0;
351     NET_API_STATUS status;
352 
353     /* Leave, if there is no valid listview item */
354     if (pnmv->item.iItem == -1)
355         return FALSE;
356 
357     /* Get the new user name */
358     ListView_GetItemText(pnmv->hdr.hwndFrom,
359                          pnmv->item.iItem, 0,
360                          szOldGroupName,
361                          UNLEN);
362 
363     /* Leave, if the user canceled the edit action */
364     if (pnmv->item.pszText == NULL)
365         return FALSE;
366 
367     /* Get the new user name */
368     lstrcpy(szNewGroupName, pnmv->item.pszText);
369 
370     /* Leave, if the user name was not changed */
371     if (lstrcmp(szOldGroupName, szNewGroupName) == 0)
372         return FALSE;
373 
374     /* Check the group name for illegal characters */
375     if (!CheckAccountName(NULL, 0, szNewGroupName))
376         return FALSE;
377 
378     /* Change the user name */
379     lgrpi0.lgrpi0_name = szNewGroupName;
380 
381 #if 0
382     status = NetLocalGroupSetInfo(NULL, szOldGroupName, 0, (LPBYTE)&lgrpi0, NULL);
383 #else
384     status = NERR_Success;
385 #endif
386     if (status != NERR_Success)
387     {
388         TCHAR szText[256];
389         wsprintf(szText, TEXT("Error: %u"), status);
390         MessageBox(NULL, szText, TEXT("NetLocalGroupSetInfo"), MB_ICONERROR | MB_OK);
391         return FALSE;
392     }
393 
394     /* Update the listview item */
395     ListView_SetItemText(pnmv->hdr.hwndFrom,
396                          pnmv->item.iItem, 0,
397                          szNewGroupName);
398 
399     return TRUE;
400 }
401 
402 
403 static BOOL
404 OnNotify(HWND hwndDlg, PGROUP_DATA pGroupData, NMHDR *phdr)
405 {
406     LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
407 
408     switch (phdr->idFrom)
409     {
410         case IDC_GROUPS_LIST:
411             switch(phdr->code)
412             {
413                 case NM_CLICK:
414                     pGroupData->iCurrentItem = lpnmlv->iItem;
415                     break;
416 
417                 case NM_DBLCLK:
418                     if (lpnmlv->iItem != -1)
419                     {
420                         UINT uItem;
421 
422                         uItem =  GetMenuDefaultItem(GetSubMenu(pGroupData->hPopupMenu, 1),
423                                                     FALSE, 0);
424                         if (uItem != (UINT)-1)
425                             SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(uItem, 0), 0);
426                     }
427                     break;
428 
429                 case NM_RCLICK:
430                     ClientToScreen(GetDlgItem(hwndDlg, IDC_GROUPS_LIST), &lpnmlv->ptAction);
431                     TrackPopupMenu(GetSubMenu(pGroupData->hPopupMenu, (lpnmlv->iItem == -1) ? 0 : 1),
432                                    TPM_LEFTALIGN, lpnmlv->ptAction.x, lpnmlv->ptAction.y, 0, hwndDlg, NULL);
433                     break;
434 
435                 case LVN_BEGINLABELEDIT:
436                     return OnBeginLabelEdit((LPNMLVDISPINFO)phdr);
437 
438                 case LVN_ENDLABELEDIT:
439                     return OnEndLabelEdit((LPNMLVDISPINFO)phdr);
440             }
441             break;
442     }
443 
444     return FALSE;
445 }
446 
447 
448 INT_PTR CALLBACK
449 GroupsPageProc(HWND hwndDlg,
450                UINT uMsg,
451                WPARAM wParam,
452                LPARAM lParam)
453 {
454     PGROUP_DATA pGroupData;
455 
456     UNREFERENCED_PARAMETER(lParam);
457     UNREFERENCED_PARAMETER(wParam);
458     UNREFERENCED_PARAMETER(hwndDlg);
459 
460 
461     pGroupData = (PGROUP_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
462 
463     switch (uMsg)
464     {
465         case WM_INITDIALOG:
466             pGroupData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GROUP_DATA));
467             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGroupData);
468 
469             pGroupData->hPopupMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDM_POPUP_GROUP));
470 
471             OnInitDialog(hwndDlg);
472             SetMenuDefaultItem(GetSubMenu(pGroupData->hPopupMenu, 1),
473                                IDM_GROUP_PROPERTIES,
474                                FALSE);
475             break;
476 
477         case WM_COMMAND:
478             switch (LOWORD(wParam))
479             {
480                 case IDM_GROUP_NEW:
481                     GroupNew(hwndDlg);
482                     break;
483 
484                 case IDM_GROUP_RENAME:
485                     GroupRename(hwndDlg);
486                     break;
487 
488                 case IDM_GROUP_DELETE:
489                     GroupDelete(hwndDlg);
490                     break;
491 
492                 case IDM_GROUP_PROPERTIES:
493                     if (GroupProperties(hwndDlg) == IDOK)
494                         UpdateGroupProperties(hwndDlg);
495                     break;
496             }
497             break;
498 
499         case WM_NOTIFY:
500             return OnNotify(hwndDlg, pGroupData, (NMHDR *)lParam);
501 
502         case WM_DESTROY:
503             DestroyMenu(pGroupData->hPopupMenu);
504             HeapFree(GetProcessHeap(), 0, pGroupData);
505             break;
506     }
507 
508     return FALSE;
509 }
510