1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS User Manager Control Panel
4 * FILE: dll/cpl/usrmgr/groupprops.c
5 * PURPOSE: Group property sheet
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 #include "usrmgr.h"
11
12 typedef struct _GENERAL_GROUP_DATA
13 {
14 TCHAR szGroupName[1];
15 } GENERAL_GROUP_DATA, *PGENERAL_GROUP_DATA;
16
17
18 static VOID
GetTextSid(PSID pSid,LPTSTR pTextSid)19 GetTextSid(PSID pSid,
20 LPTSTR pTextSid)
21 {
22 PSID_IDENTIFIER_AUTHORITY psia;
23 DWORD dwSubAuthorities;
24 DWORD dwSidRev = SID_REVISION;
25 DWORD dwCounter;
26 DWORD dwSidSize;
27
28 psia = GetSidIdentifierAuthority(pSid);
29
30 dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
31
32 dwSidSize = wsprintf(pTextSid, TEXT("S-%lu-"), dwSidRev);
33
34 if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
35 {
36 dwSidSize += wsprintf(pTextSid + lstrlen(pTextSid),
37 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
38 (USHORT)psia->Value[0],
39 (USHORT)psia->Value[1],
40 (USHORT)psia->Value[2],
41 (USHORT)psia->Value[3],
42 (USHORT)psia->Value[4],
43 (USHORT)psia->Value[5]);
44 }
45 else
46 {
47 dwSidSize += wsprintf(pTextSid + lstrlen(pTextSid),
48 TEXT("%lu"),
49 (ULONG)(psia->Value[5]) +
50 (ULONG)(psia->Value[4] << 8) +
51 (ULONG)(psia->Value[3] << 16) +
52 (ULONG)(psia->Value[2] << 24));
53 }
54
55 for (dwCounter = 0 ; dwCounter < dwSubAuthorities ; dwCounter++)
56 {
57 dwSidSize += wsprintf(pTextSid + dwSidSize, TEXT("-%lu"),
58 *GetSidSubAuthority(pSid, dwCounter));
59 }
60 }
61
62
63 static VOID
InitGroupMembersList(HWND hwndDlg,PGENERAL_GROUP_DATA pGroupData)64 InitGroupMembersList(HWND hwndDlg,
65 PGENERAL_GROUP_DATA pGroupData)
66 {
67 HWND hwndLV;
68 LV_COLUMN column;
69 RECT rect;
70 TCHAR szStr[32];
71 HIMAGELIST hImgList;
72 HICON hIcon;
73
74 NET_API_STATUS netStatus;
75 PUSER_INFO_20 pUserBuffer;
76 DWORD entriesread;
77 DWORD totalentries;
78 DWORD resume_handle = 0;
79 DWORD i;
80 LV_ITEM lvi;
81 INT iItem;
82
83 hwndLV = GetDlgItem(hwndDlg, IDC_USER_ADD_MEMBERSHIP_LIST);
84 GetClientRect(hwndLV, &rect);
85
86 hImgList = ImageList_Create(16,16,ILC_COLOR32 | ILC_MASK,5,5);
87 hIcon = LoadImage(hApplet,MAKEINTRESOURCE(IDI_GROUP),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
88 ImageList_AddIcon(hImgList,hIcon);
89 DestroyIcon(hIcon);
90 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
91 ImageList_AddIcon(hImgList, hIcon);
92 DestroyIcon(hIcon);
93 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOCKED_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
94 ImageList_AddIcon(hImgList, hIcon);
95 DestroyIcon(hIcon);
96
97 (void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
98 (void)ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
99
100 memset(&column, 0x00, sizeof(column));
101 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
102 column.fmt = LVCFMT_LEFT;
103 column.cx = (INT)((rect.right - rect.left) * 0.40);
104 column.iSubItem = 0;
105 LoadString(hApplet, IDS_NAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
106 column.pszText = szStr;
107 (void)ListView_InsertColumn(hwndLV, 0, &column);
108
109 column.cx = (INT)((rect.right - rect.left) * 0.60);
110 column.iSubItem = 1;
111 LoadString(hApplet, IDS_DESCRIPTION, szStr, sizeof(szStr) / sizeof(szStr[0]));
112 column.pszText = szStr;
113 (void)ListView_InsertColumn(hwndLV, 1, &column);
114
115 /* TODO: Enumerate global groups and add them to the list! */
116
117 for (;;)
118 {
119 netStatus = NetUserEnum(NULL, 20, FILTER_NORMAL_ACCOUNT,
120 (LPBYTE*)&pUserBuffer,
121 1024, &entriesread,
122 &totalentries, &resume_handle);
123 if (netStatus != NERR_Success && netStatus != ERROR_MORE_DATA)
124 break;
125
126 for (i = 0; i < entriesread; i++)
127 {
128 memset(&lvi, 0x00, sizeof(lvi));
129 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
130 lvi.pszText = pUserBuffer[i].usri20_name;
131 lvi.state = 0;
132 lvi.iImage = (pUserBuffer[i].usri20_flags & UF_ACCOUNTDISABLE) ? 2 : 1;
133 iItem = ListView_InsertItem(hwndLV, &lvi);
134
135 ListView_SetItemText(hwndLV, iItem, 1,
136 pUserBuffer[i].usri20_full_name);
137
138 ListView_SetItemText(hwndLV, iItem, 2,
139 pUserBuffer[i].usri20_comment);
140 }
141
142 NetApiBufferFree(pUserBuffer);
143
144 /* No more data left */
145 if (netStatus != ERROR_MORE_DATA)
146 break;
147 }
148 }
149
150
151 static BOOL
AddSelectedUsersToGroup(HWND hwndDlg,PGENERAL_GROUP_DATA pGroupData)152 AddSelectedUsersToGroup(HWND hwndDlg,
153 PGENERAL_GROUP_DATA pGroupData)
154 {
155 HWND hwndLV;
156 INT nSelectedItems;
157 INT nItem;
158 TCHAR szUserName[UNLEN + 1];
159 BOOL bResult = FALSE;
160 LOCALGROUP_MEMBERS_INFO_3 memberInfo;
161 NET_API_STATUS status;
162
163 hwndLV = GetDlgItem(hwndDlg, IDC_USER_ADD_MEMBERSHIP_LIST);
164
165 nSelectedItems = ListView_GetSelectedCount(hwndLV);
166 if (nSelectedItems > 0)
167 {
168 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
169 while (nItem != -1)
170 {
171 /* Get the new user name */
172 ListView_GetItemText(hwndLV,
173 nItem, 0,
174 szUserName,
175 UNLEN + 1);
176 TRACE("Selected user: %s", dbgstrx(szUserName));
177
178 memberInfo.lgrmi3_domainandname = szUserName;
179
180 status = NetLocalGroupAddMembers(NULL, pGroupData->szGroupName, 3,
181 (LPBYTE)&memberInfo, 1);
182 if (status != NERR_Success && status != ERROR_MEMBER_IN_ALIAS)
183 {
184 TCHAR szText[256];
185 wsprintf(szText, TEXT("Error: %u"), status);
186 MessageBox(NULL, szText, TEXT("NetLocalGroupAddMembers"), MB_ICONERROR | MB_OK);
187 }
188 else
189 {
190 bResult = TRUE;
191 }
192
193 nItem = ListView_GetNextItem(hwndLV, nItem, LVNI_SELECTED);
194 }
195 }
196
197 return bResult;
198 }
199
200
201 INT_PTR CALLBACK
AddUsersToGroupDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)202 AddUsersToGroupDlgProc(HWND hwndDlg,
203 UINT uMsg,
204 WPARAM wParam,
205 LPARAM lParam)
206 {
207 PGENERAL_GROUP_DATA pGroupData;
208
209 UNREFERENCED_PARAMETER(wParam);
210
211 pGroupData = (PGENERAL_GROUP_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
212
213 switch (uMsg)
214 {
215 case WM_INITDIALOG:
216 pGroupData = (PGENERAL_GROUP_DATA)lParam;
217 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pGroupData);
218 InitGroupMembersList(hwndDlg, pGroupData);
219 break;
220
221 case WM_COMMAND:
222 switch (LOWORD(wParam))
223 {
224 case IDOK:
225 if (AddSelectedUsersToGroup(hwndDlg, pGroupData))
226 EndDialog(hwndDlg, IDOK);
227 else
228 EndDialog(hwndDlg, IDCANCEL);
229 break;
230
231 case IDCANCEL:
232 EndDialog(hwndDlg, IDCANCEL);
233 break;
234 }
235 break;
236
237 default:
238 return FALSE;
239 }
240
241 return TRUE;
242 }
243
244
245 static VOID
AddUsersToGroup(HWND hwndDlg,PGENERAL_GROUP_DATA pGroupData)246 AddUsersToGroup(HWND hwndDlg,
247 PGENERAL_GROUP_DATA pGroupData)
248 {
249 HWND hwndLV;
250 // NET_API_STATUS status;
251 PLOCALGROUP_MEMBERS_INFO_1 membersInfo = NULL;
252 DWORD dwRead;
253 DWORD dwTotal;
254 DWORD_PTR resumeHandle = 0;
255 DWORD i;
256 LV_ITEM lvi;
257 TCHAR szGroupName[256];
258
259 if (DialogBoxParam(hApplet,
260 MAKEINTRESOURCE(IDD_USER_ADD_MEMBERSHIP),
261 hwndDlg,
262 AddUsersToGroupDlgProc,
263 (LPARAM)pGroupData) == IDOK)
264 {
265 hwndLV = GetDlgItem(hwndDlg, IDC_GROUP_GENERAL_MEMBERS);
266
267 (void)ListView_DeleteAllItems(hwndLV);
268
269 // DebugPrintf(_T("Removed all users from the list!"));
270
271 /* Set group members */
272 NetLocalGroupGetMembers(NULL, pGroupData->szGroupName, 1, (LPBYTE*)&membersInfo,
273 MAX_PREFERRED_LENGTH, &dwRead, &dwTotal,
274 &resumeHandle);
275
276 for (i = 0; i < dwRead; i++)
277 {
278 ZeroMemory(&lvi, sizeof(lvi));
279 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
280 lvi.pszText = membersInfo[i].lgrmi1_name;
281 lvi.state = 0;
282 lvi.iImage = (membersInfo[i].lgrmi1_sidusage == SidTypeGroup ||
283 membersInfo[i].lgrmi1_sidusage == SidTypeWellKnownGroup) ? 1 : 0;
284
285 if (membersInfo[i].lgrmi1_sidusage == SidTypeWellKnownGroup)
286 {
287 TCHAR szSid[256];
288
289 GetTextSid(membersInfo[i].lgrmi1_sid, szSid);
290
291 wsprintf(szGroupName,
292 TEXT("%s (%s)"),
293 membersInfo[i].lgrmi1_name,
294 szSid);
295
296 lvi.pszText = szGroupName;
297 }
298
299
300 (void)ListView_InsertItem(hwndLV, &lvi);
301 }
302
303 NetApiBufferFree(membersInfo);
304 }
305 }
306
307
308 static VOID
RemoveUserFromGroup(HWND hwndDlg,PGENERAL_GROUP_DATA pGroupData)309 RemoveUserFromGroup(HWND hwndDlg,
310 PGENERAL_GROUP_DATA pGroupData)
311 {
312 TCHAR szUserName[UNLEN + 1];
313 TCHAR szText[256];
314 LOCALGROUP_MEMBERS_INFO_3 memberInfo;
315 HWND hwndLV;
316 INT nItem;
317 NET_API_STATUS status;
318
319 hwndLV = GetDlgItem(hwndDlg, IDC_GROUP_GENERAL_MEMBERS);
320 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
321 if (nItem == -1)
322 return;
323
324 /* Get the new user name */
325 ListView_GetItemText(hwndLV,
326 nItem, 0,
327 szUserName,
328 UNLEN + 1);
329
330 /* Display a warning message because the remove operation cannot be reverted */
331 wsprintf(szText, TEXT("Do you really want to remove the user \"%s\" from the group \"%s\"?"),
332 szUserName, pGroupData->szGroupName);
333 if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO)
334 return;
335
336 memberInfo.lgrmi3_domainandname = szUserName;
337
338 status = NetLocalGroupDelMembers(NULL, pGroupData->szGroupName,
339 3, (LPBYTE)&memberInfo, 1);
340 if (status != NERR_Success)
341 {
342 TCHAR szText[256];
343 wsprintf(szText, TEXT("Error: %u"), status);
344 MessageBox(NULL, szText, TEXT("NetLocalGroupDelMembers"), MB_ICONERROR | MB_OK);
345 return;
346 }
347
348 (void)ListView_DeleteItem(hwndLV, nItem);
349
350 if (ListView_GetItemCount(hwndLV) == 0)
351 EnableWindow(GetDlgItem(hwndDlg, IDC_GROUP_GENERAL_REMOVE), FALSE);
352 }
353
354
355 static BOOL
OnGroupPropSheetNotify(HWND hwndDlg,PGENERAL_GROUP_DATA pGroupData,LPARAM lParam)356 OnGroupPropSheetNotify(HWND hwndDlg,
357 PGENERAL_GROUP_DATA pGroupData,
358 LPARAM lParam)
359 {
360 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lParam;
361
362 switch (((LPNMHDR)lParam)->idFrom)
363 {
364 case IDC_GROUP_GENERAL_MEMBERS:
365 switch (((LPNMHDR)lParam)->code)
366 {
367 case NM_CLICK:
368 EnableWindow(GetDlgItem(hwndDlg, IDC_GROUP_GENERAL_REMOVE), (lpnmlv->iItem != -1));
369 break;
370
371 case LVN_KEYDOWN:
372 if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_DELETE)
373 {
374 RemoveUserFromGroup(hwndDlg, pGroupData);
375 }
376 break;
377
378 }
379 break;
380 }
381
382 return FALSE;
383 }
384
385
386 static VOID
GetGeneralGroupData(HWND hwndDlg,PGENERAL_GROUP_DATA pGroupData)387 GetGeneralGroupData(HWND hwndDlg,
388 PGENERAL_GROUP_DATA pGroupData)
389 {
390 PLOCALGROUP_INFO_1 groupInfo = NULL;
391 PLOCALGROUP_MEMBERS_INFO_2 membersInfo = NULL;
392 DWORD dwRead;
393 DWORD dwTotal;
394 DWORD_PTR resumeHandle = 0;
395 DWORD i;
396 LV_ITEM lvi;
397 HWND hwndLV;
398 LV_COLUMN column;
399 RECT rect;
400 HIMAGELIST hImgList;
401 HICON hIcon;
402 TCHAR szGroupName[256];
403
404
405 hwndLV = GetDlgItem(hwndDlg, IDC_GROUP_GENERAL_MEMBERS);
406
407 /* Create the image list */
408 hImgList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 5, 5);
409 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_GROUP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
410 ImageList_AddIcon(hImgList, hIcon);
411 DestroyIcon(hIcon);
412 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
413 ImageList_AddIcon(hImgList, hIcon);
414 DestroyIcon(hIcon);
415
416 (void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
417
418 /* Set the list column */
419 GetClientRect(hwndLV, &rect);
420
421 memset(&column, 0x00, sizeof(column));
422 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
423 column.fmt = LVCFMT_LEFT;
424 column.cx = (INT)(rect.right - rect.left);
425 column.iSubItem = 0;
426 (void)ListView_InsertColumn(hwndLV, 0, &column);
427
428 /* Set group name */
429 SetDlgItemText(hwndDlg, IDC_GROUP_GENERAL_NAME, pGroupData->szGroupName);
430
431 /* Set group description */
432 NetLocalGroupGetInfo(NULL, pGroupData->szGroupName, 1, (LPBYTE*)&groupInfo);
433 SetDlgItemText(hwndDlg, IDC_GROUP_GENERAL_DESCRIPTION, groupInfo->lgrpi1_comment);
434 NetApiBufferFree(groupInfo);
435
436 /* Set group members */
437 NetLocalGroupGetMembers(NULL, pGroupData->szGroupName, 2, (LPBYTE*)&membersInfo,
438 MAX_PREFERRED_LENGTH, &dwRead, &dwTotal,
439 &resumeHandle);
440
441 for (i = 0; i < dwRead; i++)
442 {
443 ZeroMemory(&lvi, sizeof(lvi));
444 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
445 lvi.state = 0;
446 if (membersInfo[i].lgrmi2_sidusage == SidTypeGroup ||
447 membersInfo[i].lgrmi2_sidusage == SidTypeWellKnownGroup)
448 {
449 lvi.iImage = 0;
450 }
451 else if (membersInfo[i].lgrmi2_sidusage == SidTypeUser)
452 {
453 /* FIXME: handle locked user properly! */
454 lvi.iImage = 1;
455 }
456
457 if (membersInfo[i].lgrmi2_sidusage == SidTypeWellKnownGroup)
458 {
459 TCHAR szSid[256];
460
461 GetTextSid(membersInfo[i].lgrmi2_sid, szSid);
462
463 wsprintf(szGroupName,
464 TEXT("%s (%s)"),
465 membersInfo[i].lgrmi2_domainandname,
466 szSid);
467
468 lvi.pszText = szGroupName;
469 }
470 else
471 {
472 LPWSTR ptr;
473
474 ptr = wcschr(membersInfo[i].lgrmi2_domainandname, L'\\');
475 if (ptr != NULL)
476 {
477 lvi.pszText = ++ptr;
478 }
479 else
480 {
481 lvi.pszText = membersInfo[i].lgrmi2_domainandname;
482 }
483 }
484
485 (void)ListView_InsertItem(hwndLV, &lvi);
486 }
487
488 NetApiBufferFree(membersInfo);
489 }
490
491
492 static BOOL
SetGeneralGroupData(HWND hwndDlg,PGENERAL_GROUP_DATA pGroupData)493 SetGeneralGroupData(HWND hwndDlg,
494 PGENERAL_GROUP_DATA pGroupData)
495 {
496 LOCALGROUP_INFO_1 groupInfo;
497 NET_API_STATUS status;
498 DWORD dwIndex;
499
500 /* Get the group description */
501 groupInfo.lgrpi1_comment = GetDlgItemTextAlloc(hwndDlg, IDC_GROUP_GENERAL_DESCRIPTION);
502
503 status = NetLocalGroupSetInfo(NULL, pGroupData->szGroupName, 1, (LPBYTE)&groupInfo, &dwIndex);
504 if (status != NERR_Success)
505 {
506 ERR("NetLocalGroupSetInfo failed. Status: %lu Index: %lu", status, dwIndex);
507 }
508
509 HeapFree(GetProcessHeap(), 0, groupInfo.lgrpi1_comment);
510
511 return TRUE;
512 }
513
514
515 INT_PTR CALLBACK
GroupGeneralPageProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)516 GroupGeneralPageProc(HWND hwndDlg,
517 UINT uMsg,
518 WPARAM wParam,
519 LPARAM lParam)
520 {
521 PGENERAL_GROUP_DATA pGroupData;
522
523 UNREFERENCED_PARAMETER(lParam);
524 UNREFERENCED_PARAMETER(wParam);
525 UNREFERENCED_PARAMETER(hwndDlg);
526
527 pGroupData= (PGENERAL_GROUP_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
528
529 switch (uMsg)
530 {
531 case WM_INITDIALOG:
532 pGroupData = (PGENERAL_GROUP_DATA)HeapAlloc(GetProcessHeap(),
533 HEAP_ZERO_MEMORY,
534 sizeof(GENERAL_GROUP_DATA) +
535 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
536 lstrcpy(pGroupData->szGroupName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
537
538 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pGroupData);
539
540 GetGeneralGroupData(hwndDlg,
541 pGroupData);
542 break;
543
544 case WM_COMMAND:
545 switch (LOWORD(wParam))
546 {
547 case IDC_GROUP_GENERAL_DESCRIPTION:
548 if (HIWORD(wParam) == EN_CHANGE)
549 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
550 break;
551
552 case IDC_GROUP_GENERAL_ADD:
553 AddUsersToGroup(hwndDlg, pGroupData);
554 break;
555
556 case IDC_GROUP_GENERAL_REMOVE:
557 RemoveUserFromGroup(hwndDlg, pGroupData);
558 break;
559 }
560 break;
561
562 case WM_NOTIFY:
563 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
564 {
565 SetGeneralGroupData(hwndDlg, pGroupData);
566 return TRUE;
567 }
568 else
569 {
570 return OnGroupPropSheetNotify(hwndDlg, pGroupData, lParam);
571 }
572 break;
573
574 case WM_DESTROY:
575 HeapFree(GetProcessHeap(), 0, pGroupData);
576 break;
577 }
578
579 return FALSE;
580 }
581
582
583 static VOID
InitGroupPropSheetPage(PROPSHEETPAGE * psp,WORD idDlg,DLGPROC DlgProc,LPTSTR pszGroup)584 InitGroupPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPTSTR pszGroup)
585 {
586 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
587 psp->dwSize = sizeof(PROPSHEETPAGE);
588 psp->dwFlags = PSP_DEFAULT;
589 psp->hInstance = hApplet;
590 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
591 psp->pfnDlgProc = DlgProc;
592 psp->lParam = (LPARAM)pszGroup;
593 }
594
595
596 BOOL
GroupProperties(HWND hwndDlg)597 GroupProperties(HWND hwndDlg)
598 {
599 PROPSHEETPAGE psp[1];
600 PROPSHEETHEADER psh;
601 TCHAR szGroupName[UNLEN + 1];
602 INT nItem;
603 HWND hwndLV;
604
605 hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
606 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
607 if (nItem == -1)
608 return FALSE;
609
610 /* Get the new user name */
611 ListView_GetItemText(hwndLV,
612 nItem, 0,
613 szGroupName,
614 UNLEN + 1);
615
616 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
617 psh.dwSize = sizeof(PROPSHEETHEADER);
618 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
619 psh.hwndParent = hwndDlg;
620 psh.hInstance = hApplet;
621 psh.hIcon = NULL;
622 psh.pszCaption = szGroupName;
623 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
624 psh.nStartPage = 0;
625 psh.ppsp = psp;
626
627 InitGroupPropSheetPage(&psp[0], IDD_GROUP_GENERAL, GroupGeneralPageProc, szGroupName);
628
629 return (PropertySheet(&psh) == IDOK);
630 }
631