27ac6827620c77113935e2f1d0b536669d05430c
[reactos.git] / reactos / dll / cpl / usrmgr / userprops.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS User Manager Control Panel
4 * FILE: dll/cpl/usrmgr/userprops.c
5 * PURPOSE: User property sheet
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 #include "usrmgr.h"
11
12 typedef struct _GENERAL_USER_DATA
13 {
14 DWORD dwFlags;
15 DWORD dwPasswordExpired;
16 TCHAR szUserName[1];
17 } GENERAL_USER_DATA, *PGENERAL_USER_DATA;
18
19 #define VALID_GENERAL_FLAGS (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD | UF_ACCOUNTDISABLE | UF_LOCKOUT)
20
21
22
23 static VOID
24 GetProfileData(HWND hwndDlg, LPTSTR lpUserName)
25 {
26 PUSER_INFO_3 userInfo = NULL;
27 NET_API_STATUS status;
28 BOOL bLocal;
29 TCHAR szDrive[8];
30 INT i;
31 INT nSel;
32
33 status = NetUserGetInfo(NULL, lpUserName, 3, (LPBYTE*)&userInfo);
34 if (status != NERR_Success)
35 return;
36
37 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_PATH, userInfo->usri3_profile);
38 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_SCRIPT, userInfo->usri3_script_path);
39
40
41 bLocal = (userInfo->usri3_home_dir_drive == NULL) ||
42 (_tcslen(userInfo->usri3_home_dir_drive) == 0);
43 CheckRadioButton(hwndDlg, IDC_USER_PROFILE_LOCAL, IDC_USER_PROFILE_REMOTE,
44 bLocal ? IDC_USER_PROFILE_LOCAL : IDC_USER_PROFILE_REMOTE);
45
46 for (i = 0; i < 26; i++)
47 {
48 wsprintf(szDrive, _T("%c:"), (TCHAR)('A' + i));
49 nSel = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
50 CB_INSERTSTRING, -1, (LPARAM)szDrive);
51 }
52
53 if (bLocal)
54 {
55 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH, userInfo->usri3_home_dir);
56 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), FALSE);
57 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), FALSE);
58 }
59 else
60 {
61 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH, userInfo->usri3_home_dir);
62 nSel = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
63 CB_FINDSTRINGEXACT, -1, (LPARAM)userInfo->usri3_home_dir_drive);
64 }
65
66 SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
67 CB_SETCURSEL, nSel, 0);
68
69 NetApiBufferFree(userInfo);
70 }
71
72
73 INT_PTR CALLBACK
74 UserProfilePageProc(HWND hwndDlg,
75 UINT uMsg,
76 WPARAM wParam,
77 LPARAM lParam)
78 {
79
80 UNREFERENCED_PARAMETER(lParam);
81 UNREFERENCED_PARAMETER(wParam);
82 UNREFERENCED_PARAMETER(hwndDlg);
83
84 switch (uMsg)
85 {
86 case WM_INITDIALOG:
87 GetProfileData(hwndDlg,
88 (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
89 break;
90
91 case WM_COMMAND:
92 switch (LOWORD(wParam))
93 {
94 case IDC_USER_PROFILE_LOCAL:
95 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH), TRUE);
96 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), FALSE);
97 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), FALSE);
98 break;
99
100 case IDC_USER_PROFILE_REMOTE:
101 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH), FALSE);
102 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), TRUE);
103 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), TRUE);
104 break;
105 }
106 break;
107 }
108
109 return FALSE;
110 }
111
112
113 static VOID
114 GetMembershipData(HWND hwndDlg, LPTSTR lpUserName)
115 {
116 PLOCALGROUP_USERS_INFO_0 usersInfo = NULL;
117 NET_API_STATUS status;
118 DWORD dwRead;
119 DWORD dwTotal;
120 DWORD i;
121 HIMAGELIST hImgList;
122 HICON hIcon;
123 LV_ITEM lvi;
124 HWND hwndLV;
125 LV_COLUMN column;
126 RECT rect;
127
128
129 hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
130
131 /* Create the image list */
132 hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 5, 5);
133 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_GROUP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
134 ImageList_AddIcon(hImgList, hIcon);
135 DestroyIcon(hIcon);
136 (void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
137
138 /* Set the list column */
139 GetClientRect(hwndLV, &rect);
140
141 memset(&column, 0x00, sizeof(column));
142 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
143 column.fmt = LVCFMT_LEFT;
144 column.cx = (INT)(rect.right - rect.left);
145 column.iSubItem = 0;
146 (void)ListView_InsertColumn(hwndLV, 0, &column);
147
148
149 status = NetUserGetLocalGroups(NULL, lpUserName, 0, 0,
150 (LPBYTE*)&usersInfo,
151 MAX_PREFERRED_LENGTH,
152 &dwRead,
153 &dwTotal);
154 if (status != NERR_Success)
155 return;
156
157 for (i = 0; i < dwRead; i++)
158 {
159 ZeroMemory(&lvi, sizeof(lvi));
160 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
161 lvi.pszText = usersInfo[i].lgrui0_name;
162 lvi.state = 0;
163 lvi.iImage = 0;
164
165 (void)ListView_InsertItem(hwndLV, &lvi);
166 }
167
168
169 NetApiBufferFree(usersInfo);
170
171 }
172
173
174 INT_PTR CALLBACK
175 UserMembershipPageProc(HWND hwndDlg,
176 UINT uMsg,
177 WPARAM wParam,
178 LPARAM lParam)
179 {
180
181 UNREFERENCED_PARAMETER(lParam);
182 UNREFERENCED_PARAMETER(wParam);
183 UNREFERENCED_PARAMETER(hwndDlg);
184
185 switch (uMsg)
186 {
187 case WM_INITDIALOG:
188 GetMembershipData(hwndDlg,
189 (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
190 break;
191
192 }
193
194 return FALSE;
195 }
196
197
198 static VOID
199 UpdateUserOptions(HWND hwndDlg,
200 PGENERAL_USER_DATA pUserData,
201 BOOL bInit)
202 {
203 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE),
204 !pUserData->dwPasswordExpired);
205 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES),
206 !pUserData->dwPasswordExpired);
207 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE),
208 (pUserData->dwFlags & (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD)) == 0);
209
210 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_LOCKED),
211 (pUserData->dwFlags & UF_LOCKOUT) != 0);
212
213 if (bInit)
214 {
215 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE,
216 pUserData->dwPasswordExpired ? BST_CHECKED : BST_UNCHECKED);
217
218 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE,
219 (pUserData->dwFlags & UF_PASSWD_CANT_CHANGE) ? BST_CHECKED : BST_UNCHECKED);
220
221 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES,
222 (pUserData->dwFlags & UF_DONT_EXPIRE_PASSWD) ? BST_CHECKED : BST_UNCHECKED);
223
224 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_DISABLED,
225 (pUserData->dwFlags & UF_ACCOUNTDISABLE) ? BST_CHECKED : BST_UNCHECKED);
226
227 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_LOCKED,
228 (pUserData->dwFlags & UF_LOCKOUT) ? BST_CHECKED : BST_UNCHECKED);
229 }
230 }
231
232
233 static VOID
234 GetGeneralUserData(HWND hwndDlg,
235 PGENERAL_USER_DATA pUserData)
236 {
237 PUSER_INFO_3 pUserInfo = NULL;
238
239 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_NAME, pUserData->szUserName);
240
241 NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
242
243 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, pUserInfo->usri3_full_name);
244 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, pUserInfo->usri3_comment);
245
246 pUserData->dwFlags = pUserInfo->usri3_flags;
247 pUserData->dwPasswordExpired = pUserInfo->usri3_password_expired;
248
249 NetApiBufferFree(pUserInfo);
250
251 UpdateUserOptions(hwndDlg, pUserData, TRUE);
252 }
253
254
255 static BOOL
256 SetGeneralUserData(HWND hwndDlg,
257 PGENERAL_USER_DATA pUserData)
258 {
259 PUSER_INFO_3 pUserInfo = NULL;
260 LPTSTR pszFullName = NULL;
261 LPTSTR pszComment = NULL;
262 NET_API_STATUS status;
263 DWORD dwIndex;
264 INT nLength;
265
266 NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
267
268 pUserInfo->usri3_flags =
269 (pUserData->dwFlags & VALID_GENERAL_FLAGS) |
270 (pUserInfo->usri3_flags & ~VALID_GENERAL_FLAGS);
271
272 pUserInfo->usri3_password_expired = pUserData->dwPasswordExpired;
273
274 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FULL_NAME));
275 if (nLength == 0)
276 {
277 pUserInfo->usri3_full_name = NULL;
278 }
279 else
280 {
281 pszFullName = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
282 GetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, pszFullName, nLength + 1);
283 pUserInfo->usri3_full_name = pszFullName;
284 }
285
286 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_GENERAL_DESCRIPTION));
287 if (nLength == 0)
288 {
289 pUserInfo->usri3_full_name = NULL;
290 }
291 else
292 {
293 pszComment = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
294 GetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, pszComment, nLength + 1);
295 pUserInfo->usri3_comment = pszComment;
296 }
297
298 status = NetUserSetInfo(NULL, pUserData->szUserName, 3, (LPBYTE)pUserInfo, &dwIndex);
299 if (status != NERR_Success)
300 {
301 DebugPrintf(_T("Status: %lu Index: %lu"), status, dwIndex);
302 }
303
304 if (pszFullName)
305 HeapFree(GetProcessHeap(), 0, pszFullName);
306
307 NetApiBufferFree(pUserInfo);
308
309 return (status == NERR_Success);
310 }
311
312
313 INT_PTR CALLBACK
314 UserGeneralPageProc(HWND hwndDlg,
315 UINT uMsg,
316 WPARAM wParam,
317 LPARAM lParam)
318 {
319 PGENERAL_USER_DATA pUserData;
320
321 UNREFERENCED_PARAMETER(lParam);
322 UNREFERENCED_PARAMETER(wParam);
323 UNREFERENCED_PARAMETER(hwndDlg);
324
325 pUserData= (PGENERAL_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
326
327 switch (uMsg)
328 {
329 case WM_INITDIALOG:
330 pUserData = (PGENERAL_USER_DATA)HeapAlloc(GetProcessHeap(),
331 HEAP_ZERO_MEMORY,
332 sizeof(GENERAL_USER_DATA) +
333 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
334 lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
335
336 GetGeneralUserData(hwndDlg,
337 pUserData);
338
339 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
340 break;
341
342 case WM_COMMAND:
343 switch (LOWORD(wParam))
344 {
345 case IDC_USER_GENERAL_FORCE_CHANGE:
346 pUserData->dwPasswordExpired = !pUserData->dwPasswordExpired;
347 UpdateUserOptions(hwndDlg, pUserData, FALSE);
348 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
349 break;
350
351 case IDC_USER_GENERAL_CANNOT_CHANGE:
352 pUserData->dwFlags ^= UF_PASSWD_CANT_CHANGE;
353 UpdateUserOptions(hwndDlg, pUserData, FALSE);
354 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
355 break;
356
357 case IDC_USER_GENERAL_NEVER_EXPIRES:
358 pUserData->dwFlags ^= UF_DONT_EXPIRE_PASSWD;
359 UpdateUserOptions(hwndDlg, pUserData, FALSE);
360 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
361 break;
362
363 case IDC_USER_GENERAL_DISABLED:
364 pUserData->dwFlags ^= UF_ACCOUNTDISABLE;
365 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
366 break;
367
368 case IDC_USER_GENERAL_LOCKED:
369 pUserData->dwFlags ^= UF_LOCKOUT;
370 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
371 break;
372 }
373 break;
374
375 case WM_NOTIFY:
376 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
377 {
378 SetGeneralUserData(hwndDlg, pUserData);
379 return TRUE;
380 }
381 break;
382
383 case WM_DESTROY:
384 HeapFree(GetProcessHeap(), 0, pUserData);
385 break;
386 }
387
388 return FALSE;
389 }
390
391
392 static VOID
393 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPTSTR pszUser)
394 {
395 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
396 psp->dwSize = sizeof(PROPSHEETPAGE);
397 psp->dwFlags = PSP_DEFAULT;
398 psp->hInstance = hApplet;
399 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
400 psp->pfnDlgProc = DlgProc;
401 psp->lParam = (LPARAM)pszUser;
402 }
403
404
405 BOOL
406 UserProperties(HWND hwndDlg)
407 {
408 PROPSHEETPAGE psp[3];
409 PROPSHEETHEADER psh;
410 TCHAR szUserName[UNLEN];
411 INT nItem;
412 HWND hwndLV;
413
414 hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
415 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
416 if (nItem == -1)
417 return FALSE;
418
419 /* Get the new user name */
420 ListView_GetItemText(hwndLV,
421 nItem, 0,
422 szUserName,
423 UNLEN);
424
425 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
426 psh.dwSize = sizeof(PROPSHEETHEADER);
427 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
428 psh.hwndParent = hwndDlg;
429 psh.hInstance = hApplet;
430 psh.hIcon = NULL;
431 psh.pszCaption = szUserName;
432 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
433 psh.nStartPage = 0;
434 psh.ppsp = psp;
435
436 InitPropSheetPage(&psp[0], IDD_USER_GENERAL, (DLGPROC)UserGeneralPageProc, szUserName);
437 InitPropSheetPage(&psp[1], IDD_USER_MEMBERSHIP, (DLGPROC)UserMembershipPageProc, szUserName);
438 InitPropSheetPage(&psp[2], IDD_USER_PROFILE, (DLGPROC)UserProfilePageProc, szUserName);
439
440 return (PropertySheet(&psh) == IDOK);
441 }