- User properties:
[reactos.git] / reactos / dll / cpl / usrmgr / groupprops.c
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
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
64 GetGeneralGroupData(HWND hwndDlg,
65 PGENERAL_GROUP_DATA pGroupData)
66 {
67 PLOCALGROUP_INFO_1 groupInfo = NULL;
68 PLOCALGROUP_MEMBERS_INFO_1 membersInfo = NULL;
69 DWORD dwRead;
70 DWORD dwTotal;
71 DWORD_PTR resumeHandle = 0;
72 DWORD i;
73 LV_ITEM lvi;
74 HWND hwndLV;
75 LV_COLUMN column;
76 RECT rect;
77 HIMAGELIST hImgList;
78 HICON hIcon;
79 TCHAR szGroupName[256];
80
81
82 hwndLV = GetDlgItem(hwndDlg, IDC_GROUP_GENERAL_MEMBERS);
83
84 /* Create the image list */
85 hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 5, 5);
86 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_USER), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
87 ImageList_AddIcon(hImgList, hIcon);
88 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_GROUP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
89 ImageList_AddIcon(hImgList, hIcon);
90 DestroyIcon(hIcon);
91
92 (void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
93
94 /* Set the list column */
95 GetClientRect(hwndLV, &rect);
96
97 memset(&column, 0x00, sizeof(column));
98 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
99 column.fmt = LVCFMT_LEFT;
100 column.cx = (INT)(rect.right - rect.left);
101 column.iSubItem = 0;
102 (void)ListView_InsertColumn(hwndLV, 0, &column);
103
104 /* Set group name */
105 SetDlgItemText(hwndDlg, IDC_GROUP_GENERAL_NAME, pGroupData->szGroupName);
106
107 /* Set group description */
108 NetLocalGroupGetInfo(NULL, pGroupData->szGroupName, 1, (LPBYTE*)&groupInfo);
109 SetDlgItemText(hwndDlg, IDC_GROUP_GENERAL_DESCRIPTION, groupInfo->lgrpi1_comment);
110 NetApiBufferFree(groupInfo);
111
112 /* Set group members */
113 NetLocalGroupGetMembers(NULL, pGroupData->szGroupName, 1, (LPBYTE*)&membersInfo,
114 MAX_PREFERRED_LENGTH, &dwRead, &dwTotal,
115 &resumeHandle);
116
117 for (i = 0; i < dwRead; i++)
118 {
119 ZeroMemory(&lvi, sizeof(lvi));
120 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
121 lvi.pszText = membersInfo[i].lgrmi1_name;
122 lvi.state = 0;
123 lvi.iImage = (membersInfo[i].lgrmi1_sidusage == SidTypeGroup ||
124 membersInfo[i].lgrmi1_sidusage == SidTypeWellKnownGroup) ? 1 : 0;
125
126 if (membersInfo[i].lgrmi1_sidusage == SidTypeWellKnownGroup)
127 {
128 TCHAR szSid[256];
129
130 GetTextSid(membersInfo[i].lgrmi1_sid, szSid);
131
132 wsprintf(szGroupName,
133 TEXT("%s\\%s (%s)"),
134 membersInfo[i].lgrmi1_name,
135 szSid);
136
137 lvi.pszText = szGroupName;
138 }
139
140 (void)ListView_InsertItem(hwndLV, &lvi);
141 }
142
143 NetApiBufferFree(membersInfo);
144 }
145
146
147 static BOOL
148 SetGeneralGroupData(HWND hwndDlg,
149 PGENERAL_GROUP_DATA pGroupData)
150 {
151 LOCALGROUP_INFO_1 groupInfo;
152 LPTSTR pszComment = NULL;
153 INT nLength;
154 NET_API_STATUS status;
155 DWORD dwIndex;
156
157 /* Get the group description */
158 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_GROUP_GENERAL_DESCRIPTION));
159 if (nLength == 0)
160 {
161 groupInfo.lgrpi1_comment = NULL;
162 }
163 else
164 {
165 pszComment = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
166 GetDlgItemText(hwndDlg, IDC_GROUP_GENERAL_DESCRIPTION, pszComment, nLength + 1);
167 groupInfo.lgrpi1_comment = pszComment;
168 }
169
170 status = NetLocalGroupSetInfo(NULL, pGroupData->szGroupName, 1, (LPBYTE)&groupInfo, &dwIndex);
171 if (status != NERR_Success)
172 {
173 DebugPrintf(_T("Status: %lu Index: %lu"), status, dwIndex);
174 }
175
176 if (pszComment)
177 HeapFree(GetProcessHeap(), 0, pszComment);
178
179 return TRUE;
180 }
181
182
183 INT_PTR CALLBACK
184 GroupGeneralPageProc(HWND hwndDlg,
185 UINT uMsg,
186 WPARAM wParam,
187 LPARAM lParam)
188 {
189 PGENERAL_GROUP_DATA pGroupData;
190
191 UNREFERENCED_PARAMETER(lParam);
192 UNREFERENCED_PARAMETER(wParam);
193 UNREFERENCED_PARAMETER(hwndDlg);
194
195 pGroupData= (PGENERAL_GROUP_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
196
197 switch (uMsg)
198 {
199 case WM_INITDIALOG:
200 pGroupData = (PGENERAL_GROUP_DATA)HeapAlloc(GetProcessHeap(),
201 HEAP_ZERO_MEMORY,
202 sizeof(GENERAL_GROUP_DATA) +
203 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
204 lstrcpy(pGroupData->szGroupName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
205
206 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pGroupData);
207
208 GetGeneralGroupData(hwndDlg,
209 pGroupData);
210 break;
211
212 case WM_COMMAND:
213 switch (LOWORD(wParam))
214 {
215 case IDC_GROUP_GENERAL_DESCRIPTION:
216 if (HIWORD(wParam) == EN_CHANGE)
217 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
218 break;
219 }
220 break;
221
222 case WM_NOTIFY:
223 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
224 {
225 SetGeneralGroupData(hwndDlg, pGroupData);
226 return TRUE;
227 }
228 break;
229
230 case WM_DESTROY:
231 HeapFree(GetProcessHeap(), 0, pGroupData);
232 break;
233 }
234
235 return FALSE;
236 }
237
238
239 static VOID
240 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPTSTR pszGroup)
241 {
242 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
243 psp->dwSize = sizeof(PROPSHEETPAGE);
244 psp->dwFlags = PSP_DEFAULT;
245 psp->hInstance = hApplet;
246 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
247 psp->pfnDlgProc = DlgProc;
248 psp->lParam = (LPARAM)pszGroup;
249 }
250
251
252 BOOL
253 GroupProperties(HWND hwndDlg)
254 {
255 PROPSHEETPAGE psp[1];
256 PROPSHEETHEADER psh;
257 TCHAR szGroupName[UNLEN];
258 INT nItem;
259 HWND hwndLV;
260
261 hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
262 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
263 if (nItem == -1)
264 return FALSE;
265
266 /* Get the new user name */
267 ListView_GetItemText(hwndLV,
268 nItem, 0,
269 szGroupName,
270 UNLEN);
271
272 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
273 psh.dwSize = sizeof(PROPSHEETHEADER);
274 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
275 psh.hwndParent = hwndDlg;
276 psh.hInstance = hApplet;
277 psh.hIcon = NULL;
278 psh.pszCaption = szGroupName;
279 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
280 psh.nStartPage = 0;
281 psh.ppsp = psp;
282
283 InitPropSheetPage(&psp[0], IDD_GROUP_GENERAL, (DLGPROC)GroupGeneralPageProc, szGroupName);
284
285 return (PropertySheet(&psh) == IDOK);
286 }