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
7 * PROGRAMMERS: Eric Kohl
12 typedef struct _GENERAL_GROUP_DATA
15 } GENERAL_GROUP_DATA
, *PGENERAL_GROUP_DATA
;
22 PSID_IDENTIFIER_AUTHORITY psia
;
23 DWORD dwSubAuthorities
;
24 DWORD dwSidRev
= SID_REVISION
;
28 psia
= GetSidIdentifierAuthority(pSid
);
30 dwSubAuthorities
= *GetSidSubAuthorityCount(pSid
);
32 dwSidSize
= wsprintf(pTextSid
, TEXT("S-%lu-"), dwSidRev
);
34 if ((psia
->Value
[0] != 0) || (psia
->Value
[1] != 0))
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]);
47 dwSidSize
+= wsprintf(pTextSid
+ lstrlen(pTextSid
),
49 (ULONG
)(psia
->Value
[5]) +
50 (ULONG
)(psia
->Value
[4] << 8) +
51 (ULONG
)(psia
->Value
[3] << 16) +
52 (ULONG
)(psia
->Value
[2] << 24));
55 for (dwCounter
= 0 ; dwCounter
< dwSubAuthorities
; dwCounter
++)
57 dwSidSize
+= wsprintf(pTextSid
+ dwSidSize
, TEXT("-%lu"),
58 *GetSidSubAuthority(pSid
, dwCounter
));
64 InitGroupMembersList(HWND hwndDlg
,
65 PGENERAL_GROUP_DATA pGroupData
)
74 NET_API_STATUS netStatus
;
75 PUSER_INFO_20 pUserBuffer
;
78 DWORD resume_handle
= 0;
83 hwndLV
= GetDlgItem(hwndDlg
, IDC_USER_ADD_MEMBERSHIP_LIST
);
84 GetClientRect(hwndLV
, &rect
);
86 hImgList
= ImageList_Create(16,16,ILC_COLOR8
| ILC_MASK
,5,5);
87 hIcon
= LoadImage(hApplet
,MAKEINTRESOURCE(IDI_GROUP
),IMAGE_ICON
,16,16,LR_DEFAULTCOLOR
);
88 ImageList_AddIcon(hImgList
,hIcon
);
90 hIcon
= LoadImage(hApplet
, MAKEINTRESOURCE(IDI_USER
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
91 ImageList_AddIcon(hImgList
, hIcon
);
93 hIcon
= LoadImage(hApplet
, MAKEINTRESOURCE(IDI_LOCKED_USER
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
94 ImageList_AddIcon(hImgList
, hIcon
);
97 (void)ListView_SetImageList(hwndLV
, hImgList
, LVSIL_SMALL
);
98 (void)ListView_SetExtendedListViewStyle(hwndLV
, LVS_EX_FULLROWSELECT
);
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);
105 LoadString(hApplet
, IDS_NAME
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
106 column
.pszText
= szStr
;
107 (void)ListView_InsertColumn(hwndLV
, 0, &column
);
109 column
.cx
= (INT
)((rect
.right
- rect
.left
) * 0.60);
111 LoadString(hApplet
, IDS_DESCRIPTION
, szStr
, sizeof(szStr
) / sizeof(szStr
[0]));
112 column
.pszText
= szStr
;
113 (void)ListView_InsertColumn(hwndLV
, 1, &column
);
115 /* TODO: Enumerate global groups and add them to the list! */
119 netStatus
= NetUserEnum(NULL
, 20, FILTER_NORMAL_ACCOUNT
,
120 (LPBYTE
*)&pUserBuffer
,
122 &totalentries
, &resume_handle
);
123 if (netStatus
!= NERR_Success
&& netStatus
!= ERROR_MORE_DATA
)
126 for (i
= 0; i
< entriesread
; i
++)
128 memset(&lvi
, 0x00, sizeof(lvi
));
129 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_IMAGE
;
130 lvi
.pszText
= pUserBuffer
[i
].usri20_name
;
132 lvi
.iImage
= (pUserBuffer
[i
].usri20_flags
& UF_ACCOUNTDISABLE
) ? 2 : 1;
133 iItem
= ListView_InsertItem(hwndLV
, &lvi
);
135 ListView_SetItemText(hwndLV
, iItem
, 1,
136 pUserBuffer
[i
].usri20_full_name
);
138 ListView_SetItemText(hwndLV
, iItem
, 2,
139 pUserBuffer
[i
].usri20_comment
);
142 NetApiBufferFree(&pUserBuffer
);
144 /* No more data left */
145 if (netStatus
!= ERROR_MORE_DATA
)
152 AddSelectedUsersToGroup(HWND hwndDlg
,
153 PGENERAL_GROUP_DATA pGroupData
)
158 TCHAR szUserName
[UNLEN
];
159 BOOL bResult
= FALSE
;
160 LOCALGROUP_MEMBERS_INFO_3 memberInfo
;
161 NET_API_STATUS status
;
163 hwndLV
= GetDlgItem(hwndDlg
, IDC_USER_ADD_MEMBERSHIP_LIST
);
165 nSelectedItems
= ListView_GetSelectedCount(hwndLV
);
166 if (nSelectedItems
> 0)
168 nItem
= ListView_GetNextItem(hwndLV
, -1, LVNI_SELECTED
);
171 /* Get the new user name */
172 ListView_GetItemText(hwndLV
,
177 DebugPrintf(_TEXT("Selected user: %s"), szUserName
);
179 memberInfo
.lgrmi3_domainandname
= szUserName
;
181 status
= NetLocalGroupAddMembers(NULL
, pGroupData
->szGroupName
, 3,
182 (LPBYTE
)&memberInfo
, 1);
183 if (status
!= NERR_Success
&& status
!= ERROR_MEMBER_IN_ALIAS
)
186 wsprintf(szText
, TEXT("Error: %u"), status
);
187 MessageBox(NULL
, szText
, TEXT("NetLocalGroupAddMembers"), MB_ICONERROR
| MB_OK
);
194 nItem
= ListView_GetNextItem(hwndLV
, nItem
, LVNI_SELECTED
);
203 AddUsersToGroupDlgProc(HWND hwndDlg
,
208 PGENERAL_GROUP_DATA pGroupData
;
210 UNREFERENCED_PARAMETER(wParam
);
212 pGroupData
= (PGENERAL_GROUP_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
217 pGroupData
= (PGENERAL_GROUP_DATA
)lParam
;
218 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (INT_PTR
)pGroupData
);
219 InitGroupMembersList(hwndDlg
, pGroupData
);
223 switch (LOWORD(wParam
))
226 if (AddSelectedUsersToGroup(hwndDlg
, pGroupData
))
227 EndDialog(hwndDlg
, IDOK
);
229 EndDialog(hwndDlg
, IDCANCEL
);
233 EndDialog(hwndDlg
, IDCANCEL
);
247 AddUsersToGroup(HWND hwndDlg
,
248 PGENERAL_GROUP_DATA pGroupData
)
251 // NET_API_STATUS status;
252 PLOCALGROUP_MEMBERS_INFO_1 membersInfo
= NULL
;
255 DWORD_PTR resumeHandle
= 0;
258 TCHAR szGroupName
[256];
260 if (DialogBoxParam(hApplet
,
261 MAKEINTRESOURCE(IDD_USER_ADD_MEMBERSHIP
),
263 AddUsersToGroupDlgProc
,
264 (LPARAM
)pGroupData
) == IDOK
)
266 hwndLV
= GetDlgItem(hwndDlg
, IDC_GROUP_GENERAL_MEMBERS
);
268 (void)ListView_DeleteAllItems(hwndLV
);
270 // DebugPrintf(_T("Removed all users from the list!"));
272 /* Set group members */
273 NetLocalGroupGetMembers(NULL
, pGroupData
->szGroupName
, 1, (LPBYTE
*)&membersInfo
,
274 MAX_PREFERRED_LENGTH
, &dwRead
, &dwTotal
,
277 for (i
= 0; i
< dwRead
; i
++)
279 ZeroMemory(&lvi
, sizeof(lvi
));
280 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_IMAGE
;
281 lvi
.pszText
= membersInfo
[i
].lgrmi1_name
;
283 lvi
.iImage
= (membersInfo
[i
].lgrmi1_sidusage
== SidTypeGroup
||
284 membersInfo
[i
].lgrmi1_sidusage
== SidTypeWellKnownGroup
) ? 1 : 0;
286 if (membersInfo
[i
].lgrmi1_sidusage
== SidTypeWellKnownGroup
)
290 GetTextSid(membersInfo
[i
].lgrmi1_sid
, szSid
);
292 wsprintf(szGroupName
,
294 membersInfo
[i
].lgrmi1_name
,
297 lvi
.pszText
= szGroupName
;
301 (void)ListView_InsertItem(hwndLV
, &lvi
);
304 NetApiBufferFree(membersInfo
);
310 RemoveUserFromGroup(HWND hwndDlg
,
311 PGENERAL_GROUP_DATA pGroupData
)
313 TCHAR szUserName
[UNLEN
];
315 LOCALGROUP_MEMBERS_INFO_3 memberInfo
;
318 NET_API_STATUS status
;
320 hwndLV
= GetDlgItem(hwndDlg
, IDC_GROUP_GENERAL_MEMBERS
);
321 nItem
= ListView_GetNextItem(hwndLV
, -1, LVNI_SELECTED
);
325 /* Get the new user name */
326 ListView_GetItemText(hwndLV
,
331 /* Display a warning message because the remove operation cannot be reverted */
332 wsprintf(szText
, TEXT("Do you really want to remove the user \"%s\" from the group \"%s\"?"),
333 szUserName
, pGroupData
->szGroupName
);
334 if (MessageBox(NULL
, szText
, TEXT("User Accounts"), MB_ICONWARNING
| MB_YESNO
) == IDNO
)
337 memberInfo
.lgrmi3_domainandname
= szUserName
;
339 status
= NetLocalGroupDelMembers(NULL
, pGroupData
->szGroupName
,
340 3, (LPBYTE
)&memberInfo
, 1);
341 if (status
!= NERR_Success
)
344 wsprintf(szText
, TEXT("Error: %u"), status
);
345 MessageBox(NULL
, szText
, TEXT("NetLocalGroupDelMembers"), MB_ICONERROR
| MB_OK
);
349 (void)ListView_DeleteItem(hwndLV
, nItem
);
351 if (ListView_GetItemCount(hwndLV
) == 0)
352 EnableWindow(GetDlgItem(hwndDlg
, IDC_GROUP_GENERAL_REMOVE
), FALSE
);
357 OnNotify(HWND hwndDlg
,
358 PGENERAL_GROUP_DATA pGroupData
,
361 LPNMLISTVIEW lpnmlv
= (LPNMLISTVIEW
)lParam
;
363 switch (((LPNMHDR
)lParam
)->idFrom
)
365 case IDC_GROUP_GENERAL_MEMBERS
:
366 switch (((LPNMHDR
)lParam
)->code
)
369 EnableWindow(GetDlgItem(hwndDlg
, IDC_GROUP_GENERAL_REMOVE
), (lpnmlv
->iItem
!= -1));
373 if (((LPNMLVKEYDOWN
)lParam
)->wVKey
== VK_DELETE
)
375 RemoveUserFromGroup(hwndDlg
, pGroupData
);
388 GetGeneralGroupData(HWND hwndDlg
,
389 PGENERAL_GROUP_DATA pGroupData
)
391 PLOCALGROUP_INFO_1 groupInfo
= NULL
;
392 PLOCALGROUP_MEMBERS_INFO_1 membersInfo
= NULL
;
395 DWORD_PTR resumeHandle
= 0;
403 TCHAR szGroupName
[256];
406 hwndLV
= GetDlgItem(hwndDlg
, IDC_GROUP_GENERAL_MEMBERS
);
408 /* Create the image list */
409 hImgList
= ImageList_Create(16, 16, ILC_COLOR8
| ILC_MASK
, 5, 5);
410 hIcon
= LoadImage(hApplet
, MAKEINTRESOURCE(IDI_GROUP
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
411 ImageList_AddIcon(hImgList
, hIcon
);
413 hIcon
= LoadImage(hApplet
, MAKEINTRESOURCE(IDI_USER
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
414 ImageList_AddIcon(hImgList
, hIcon
);
417 (void)ListView_SetImageList(hwndLV
, hImgList
, LVSIL_SMALL
);
419 /* Set the list column */
420 GetClientRect(hwndLV
, &rect
);
422 memset(&column
, 0x00, sizeof(column
));
423 column
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_SUBITEM
;
424 column
.fmt
= LVCFMT_LEFT
;
425 column
.cx
= (INT
)(rect
.right
- rect
.left
);
427 (void)ListView_InsertColumn(hwndLV
, 0, &column
);
430 SetDlgItemText(hwndDlg
, IDC_GROUP_GENERAL_NAME
, pGroupData
->szGroupName
);
432 /* Set group description */
433 NetLocalGroupGetInfo(NULL
, pGroupData
->szGroupName
, 1, (LPBYTE
*)&groupInfo
);
434 SetDlgItemText(hwndDlg
, IDC_GROUP_GENERAL_DESCRIPTION
, groupInfo
->lgrpi1_comment
);
435 NetApiBufferFree(groupInfo
);
437 /* Set group members */
438 NetLocalGroupGetMembers(NULL
, pGroupData
->szGroupName
, 1, (LPBYTE
*)&membersInfo
,
439 MAX_PREFERRED_LENGTH
, &dwRead
, &dwTotal
,
442 for (i
= 0; i
< dwRead
; i
++)
444 ZeroMemory(&lvi
, sizeof(lvi
));
445 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_IMAGE
;
446 lvi
.pszText
= membersInfo
[i
].lgrmi1_name
;
448 if (membersInfo
[i
].lgrmi1_sidusage
== SidTypeGroup
||
449 membersInfo
[i
].lgrmi1_sidusage
== SidTypeWellKnownGroup
)
453 else if (membersInfo
[i
].lgrmi1_sidusage
== SidTypeUser
)
455 /* FIXME: handle locked user properly! */
459 if (membersInfo
[i
].lgrmi1_sidusage
== SidTypeWellKnownGroup
)
463 GetTextSid(membersInfo
[i
].lgrmi1_sid
, szSid
);
465 wsprintf(szGroupName
,
467 membersInfo
[i
].lgrmi1_name
,
470 lvi
.pszText
= szGroupName
;
473 (void)ListView_InsertItem(hwndLV
, &lvi
);
476 NetApiBufferFree(membersInfo
);
481 SetGeneralGroupData(HWND hwndDlg
,
482 PGENERAL_GROUP_DATA pGroupData
)
484 LOCALGROUP_INFO_1 groupInfo
;
485 LPTSTR pszComment
= NULL
;
487 NET_API_STATUS status
;
490 /* Get the group description */
491 nLength
= GetWindowTextLength(GetDlgItem(hwndDlg
, IDC_GROUP_GENERAL_DESCRIPTION
));
494 groupInfo
.lgrpi1_comment
= NULL
;
498 pszComment
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(TCHAR
));
499 GetDlgItemText(hwndDlg
, IDC_GROUP_GENERAL_DESCRIPTION
, pszComment
, nLength
+ 1);
500 groupInfo
.lgrpi1_comment
= pszComment
;
503 status
= NetLocalGroupSetInfo(NULL
, pGroupData
->szGroupName
, 1, (LPBYTE
)&groupInfo
, &dwIndex
);
504 if (status
!= NERR_Success
)
506 DebugPrintf(_T("Status: %lu Index: %lu"), status
, dwIndex
);
510 HeapFree(GetProcessHeap(), 0, pszComment
);
517 GroupGeneralPageProc(HWND hwndDlg
,
522 PGENERAL_GROUP_DATA pGroupData
;
524 UNREFERENCED_PARAMETER(lParam
);
525 UNREFERENCED_PARAMETER(wParam
);
526 UNREFERENCED_PARAMETER(hwndDlg
);
528 pGroupData
= (PGENERAL_GROUP_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
533 pGroupData
= (PGENERAL_GROUP_DATA
)HeapAlloc(GetProcessHeap(),
535 sizeof(GENERAL_GROUP_DATA
) +
536 lstrlen((LPTSTR
)((PROPSHEETPAGE
*)lParam
)->lParam
) * sizeof(TCHAR
));
537 lstrcpy(pGroupData
->szGroupName
, (LPTSTR
)((PROPSHEETPAGE
*)lParam
)->lParam
);
539 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (INT_PTR
)pGroupData
);
541 GetGeneralGroupData(hwndDlg
,
546 switch (LOWORD(wParam
))
548 case IDC_GROUP_GENERAL_DESCRIPTION
:
549 if (HIWORD(wParam
) == EN_CHANGE
)
550 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
553 case IDC_GROUP_GENERAL_ADD
:
554 AddUsersToGroup(hwndDlg
, pGroupData
);
557 case IDC_GROUP_GENERAL_REMOVE
:
558 RemoveUserFromGroup(hwndDlg
, pGroupData
);
564 if (((LPPSHNOTIFY
)lParam
)->hdr
.code
== PSN_APPLY
)
566 SetGeneralGroupData(hwndDlg
, pGroupData
);
571 return OnNotify(hwndDlg
, pGroupData
, lParam
);
576 HeapFree(GetProcessHeap(), 0, pGroupData
);
585 InitPropSheetPage(PROPSHEETPAGE
*psp
, WORD idDlg
, DLGPROC DlgProc
, LPTSTR pszGroup
)
587 ZeroMemory(psp
, sizeof(PROPSHEETPAGE
));
588 psp
->dwSize
= sizeof(PROPSHEETPAGE
);
589 psp
->dwFlags
= PSP_DEFAULT
;
590 psp
->hInstance
= hApplet
;
591 psp
->pszTemplate
= MAKEINTRESOURCE(idDlg
);
592 psp
->pfnDlgProc
= DlgProc
;
593 psp
->lParam
= (LPARAM
)pszGroup
;
598 GroupProperties(HWND hwndDlg
)
600 PROPSHEETPAGE psp
[1];
602 TCHAR szGroupName
[UNLEN
];
606 hwndLV
= GetDlgItem(hwndDlg
, IDC_GROUPS_LIST
);
607 nItem
= ListView_GetNextItem(hwndLV
, -1, LVNI_SELECTED
);
611 /* Get the new user name */
612 ListView_GetItemText(hwndLV
,
617 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
618 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
619 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_PROPTITLE
;
620 psh
.hwndParent
= hwndDlg
;
621 psh
.hInstance
= hApplet
;
623 psh
.pszCaption
= szGroupName
;
624 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
628 InitPropSheetPage(&psp
[0], IDD_GROUP_GENERAL
, (DLGPROC
)GroupGeneralPageProc
, szGroupName
);
630 return (PropertySheet(&psh
) == IDOK
);