Implement removal of a user from a user group.
[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 typedef struct _PROFILE_USER_DATA
22 {
23 TCHAR szUserName[1];
24 } PROFILE_USER_DATA, *PPROFILE_USER_DATA;
25
26 typedef struct _MEMBERSHIP_USER_DATA
27 {
28 PLOCALGROUP_USERS_INFO_0 pGroupData;
29 DWORD dwGroupCount;
30 TCHAR szUserName[1];
31 } MEMBERSHIP_USER_DATA, *PMEMBERSHIP_USER_DATA;
32
33
34 static VOID
35 GetUserProfileData(HWND hwndDlg,
36 PPROFILE_USER_DATA pUserData)
37 {
38 PUSER_INFO_3 userInfo = NULL;
39 NET_API_STATUS status;
40 BOOL bLocal;
41 TCHAR szDrive[8];
42 INT i;
43 INT nSel;
44
45 status = NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&userInfo);
46 if (status != NERR_Success)
47 return;
48
49 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_PATH, userInfo->usri3_profile);
50 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_SCRIPT, userInfo->usri3_script_path);
51
52
53 bLocal = (userInfo->usri3_home_dir_drive == NULL) ||
54 (_tcslen(userInfo->usri3_home_dir_drive) == 0);
55 CheckRadioButton(hwndDlg, IDC_USER_PROFILE_LOCAL, IDC_USER_PROFILE_REMOTE,
56 bLocal ? IDC_USER_PROFILE_LOCAL : IDC_USER_PROFILE_REMOTE);
57
58 for (i = 0; i < 26; i++)
59 {
60 wsprintf(szDrive, _T("%c:"), (TCHAR)('A' + i));
61 nSel = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
62 CB_INSERTSTRING, -1, (LPARAM)szDrive);
63 }
64
65 if (bLocal)
66 {
67 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH, userInfo->usri3_home_dir);
68 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), FALSE);
69 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), FALSE);
70 }
71 else
72 {
73 SetDlgItemText(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH, userInfo->usri3_home_dir);
74 nSel = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
75 CB_FINDSTRINGEXACT, -1, (LPARAM)userInfo->usri3_home_dir_drive);
76 }
77
78 SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
79 CB_SETCURSEL, nSel, 0);
80
81 NetApiBufferFree(userInfo);
82 }
83
84
85 static BOOL
86 SetUserProfileData(HWND hwndDlg,
87 PPROFILE_USER_DATA pUserData)
88 {
89 PUSER_INFO_3 pUserInfo = NULL;
90 LPTSTR pszProfilePath = NULL;
91 LPTSTR pszScriptPath = NULL;
92 LPTSTR pszHomeDir = NULL;
93 LPTSTR pszHomeDrive = NULL;
94 NET_API_STATUS status;
95 #if 0
96 DWORD dwIndex;
97 #endif
98 INT nLength;
99 INT nIndex;
100
101 NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
102
103 /* Get the profile path */
104 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_PATH));
105 if (nLength == 0)
106 {
107 pUserInfo->usri3_profile = NULL;
108 }
109 else
110 {
111 pszProfilePath = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
112 GetDlgItemText(hwndDlg, IDC_USER_PROFILE_PATH, pszProfilePath, nLength + 1);
113 pUserInfo->usri3_profile = pszProfilePath;
114 }
115
116 /* Get the script path */
117 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_SCRIPT));
118 if (nLength == 0)
119 {
120 pUserInfo->usri3_script_path = NULL;
121 }
122 else
123 {
124 pszScriptPath = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
125 GetDlgItemText(hwndDlg, IDC_USER_PROFILE_SCRIPT, pszScriptPath, nLength + 1);
126 pUserInfo->usri3_script_path = pszScriptPath;
127 }
128
129 if (IsDlgButtonChecked(hwndDlg, IDC_USER_PROFILE_LOCAL) == BST_CHECKED)
130 {
131 /* Local home directory */
132 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH));
133 if (nLength == 0)
134 {
135 pUserInfo->usri3_home_dir = NULL;
136 }
137 else
138 {
139 pszHomeDir = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
140 GetDlgItemText(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH, pszHomeDir, nLength + 1);
141 pUserInfo->usri3_home_dir = pszHomeDir;
142 }
143 }
144 else
145 {
146 /* Remote home directory */
147 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH));
148 if (nLength == 0)
149 {
150 pUserInfo->usri3_home_dir = NULL;
151 }
152 else
153 {
154 pszHomeDir = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
155 GetDlgItemText(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH, pszHomeDir, nLength + 1);
156 pUserInfo->usri3_home_dir = pszHomeDir;
157 }
158
159 nIndex = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETCURSEL, 0, 0);
160 if (nIndex != CB_ERR)
161 {
162 nLength = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETLBTEXTLEN, nIndex, 0);
163 pszHomeDrive = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
164 SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETLBTEXT, nIndex, (LPARAM)pszHomeDrive);
165 pUserInfo->usri3_home_dir_drive = pszHomeDrive;
166 }
167 }
168
169 #if 0
170 status = NetUserSetInfo(NULL, pUserData->szUserName, 3, (LPBYTE)pUserInfo, &dwIndex);
171 if (status != NERR_Success)
172 {
173 DebugPrintf(_T("Status: %lu Index: %lu"), status, dwIndex);
174 }
175 #else
176 status = NERR_Success;
177 #endif
178
179 if (pszProfilePath)
180 HeapFree(GetProcessHeap(), 0, pszProfilePath);
181
182 if (pszScriptPath)
183 HeapFree(GetProcessHeap(), 0, pszScriptPath);
184
185 if (pszHomeDir)
186 HeapFree(GetProcessHeap(), 0, pszHomeDir);
187
188 if (pszHomeDrive)
189 HeapFree(GetProcessHeap(), 0, pszHomeDrive);
190
191 NetApiBufferFree(pUserInfo);
192
193 return (status == NERR_Success);
194 }
195
196
197 INT_PTR CALLBACK
198 UserProfilePageProc(HWND hwndDlg,
199 UINT uMsg,
200 WPARAM wParam,
201 LPARAM lParam)
202 {
203 PPROFILE_USER_DATA pUserData;
204
205 UNREFERENCED_PARAMETER(lParam);
206 UNREFERENCED_PARAMETER(wParam);
207 UNREFERENCED_PARAMETER(hwndDlg);
208
209 pUserData= (PPROFILE_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
210
211 switch (uMsg)
212 {
213 case WM_INITDIALOG:
214 pUserData = (PPROFILE_USER_DATA)HeapAlloc(GetProcessHeap(),
215 HEAP_ZERO_MEMORY,
216 sizeof(PROFILE_USER_DATA) +
217 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
218 lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
219
220 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
221
222 GetUserProfileData(hwndDlg,
223 pUserData);
224 break;
225
226 case WM_COMMAND:
227 switch (LOWORD(wParam))
228 {
229 case IDC_USER_PROFILE_PATH:
230 case IDC_USER_PROFILE_SCRIPT:
231 if (HIWORD(wParam) == EN_CHANGE)
232 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
233 break;
234
235 case IDC_USER_PROFILE_LOCAL:
236 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH), TRUE);
237 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), FALSE);
238 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), FALSE);
239 break;
240
241 case IDC_USER_PROFILE_REMOTE:
242 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH), FALSE);
243 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), TRUE);
244 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), TRUE);
245 break;
246 }
247 break;
248
249 case WM_DESTROY:
250 HeapFree(GetProcessHeap(), 0, pUserData);
251 break;
252
253 case WM_NOTIFY:
254 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
255 {
256 SetUserProfileData(hwndDlg, pUserData);
257 return TRUE;
258 }
259 break;
260 }
261
262 return FALSE;
263 }
264
265
266 static VOID
267 GetUserMembershipData(HWND hwndDlg, PMEMBERSHIP_USER_DATA pUserData)
268 {
269 NET_API_STATUS status;
270 DWORD dwTotal;
271 DWORD i;
272 HIMAGELIST hImgList;
273 HICON hIcon;
274 LV_ITEM lvi;
275 HWND hwndLV;
276 LV_COLUMN column;
277 RECT rect;
278
279
280 hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
281
282 /* Create the image list */
283 hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 5, 5);
284 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_GROUP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
285 ImageList_AddIcon(hImgList, hIcon);
286 DestroyIcon(hIcon);
287 (void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
288
289 /* Set the list column */
290 GetClientRect(hwndLV, &rect);
291
292 memset(&column, 0x00, sizeof(column));
293 column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
294 column.fmt = LVCFMT_LEFT;
295 column.cx = (INT)(rect.right - rect.left);
296 column.iSubItem = 0;
297 (void)ListView_InsertColumn(hwndLV, 0, &column);
298
299
300 status = NetUserGetLocalGroups(NULL, pUserData->szUserName, 0, 0,
301 (LPBYTE*)&pUserData->pGroupData,
302 MAX_PREFERRED_LENGTH,
303 &pUserData->dwGroupCount,
304 &dwTotal);
305 if (status != NERR_Success)
306 return;
307
308 for (i = 0; i < pUserData->dwGroupCount; i++)
309 {
310 ZeroMemory(&lvi, sizeof(lvi));
311 lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
312 lvi.pszText = pUserData->pGroupData[i].lgrui0_name;
313 lvi.state = 0;
314 lvi.iImage = 0;
315
316 (void)ListView_InsertItem(hwndLV, &lvi);
317 }
318 }
319
320
321 static VOID
322 RemoveGroupFromUser(HWND hwndDlg,
323 PMEMBERSHIP_USER_DATA pUserData)
324 {
325 TCHAR szGroupName[UNLEN];
326 TCHAR szText[256];
327 LOCALGROUP_MEMBERS_INFO_3 memberInfo;
328 HWND hwndLV;
329 INT nItem;
330 NET_API_STATUS status;
331
332 hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
333 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
334 if (nItem == -1)
335 return;
336
337 /* Get the new user name */
338 ListView_GetItemText(hwndLV,
339 nItem, 0,
340 szGroupName,
341 UNLEN);
342
343 /* Display a warning message because the remove operation cannot be reverted */
344 wsprintf(szText, TEXT("Do you really want to remove the user \"%s\" from the group \"%s\"?"),
345 pUserData->szUserName, szGroupName);
346 if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO)
347 return;
348
349 memberInfo.lgrmi3_domainandname = pUserData->szUserName;
350
351 status = NetLocalGroupDelMembers(NULL, szGroupName,
352 3, (LPBYTE)&memberInfo, 1);
353 if (status != NERR_Success)
354 {
355 TCHAR szText[256];
356 wsprintf(szText, TEXT("Error: %u"), status);
357 MessageBox(NULL, szText, TEXT("NetLocalGroupDelMembers"), MB_ICONERROR | MB_OK);
358 return;
359 }
360
361 (void)ListView_DeleteItem(hwndLV, nItem);
362
363 if (ListView_GetItemCount(hwndLV) == 0)
364 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_REMOVE), FALSE);
365 }
366
367
368 static BOOL
369 OnNotify(HWND hwndDlg,
370 PMEMBERSHIP_USER_DATA pUserData,
371 LPARAM lParam)
372 {
373 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lParam;
374
375 switch (((LPNMHDR)lParam)->idFrom)
376 {
377 case IDC_USER_MEMBERSHIP_LIST:
378 switch (((LPNMHDR)lParam)->code)
379 {
380 case NM_CLICK:
381 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_REMOVE), (lpnmlv->iItem != -1));
382 break;
383
384 case LVN_KEYDOWN:
385 if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_DELETE)
386 {
387 RemoveGroupFromUser(hwndDlg, pUserData);
388 }
389 break;
390
391 }
392 break;
393 }
394
395 return FALSE;
396 }
397
398
399 INT_PTR CALLBACK
400 UserMembershipPageProc(HWND hwndDlg,
401 UINT uMsg,
402 WPARAM wParam,
403 LPARAM lParam)
404 {
405 PMEMBERSHIP_USER_DATA pUserData;
406
407 UNREFERENCED_PARAMETER(lParam);
408 UNREFERENCED_PARAMETER(wParam);
409 UNREFERENCED_PARAMETER(hwndDlg);
410
411 pUserData= (PMEMBERSHIP_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
412
413 switch (uMsg)
414 {
415 case WM_INITDIALOG:
416 pUserData = (PMEMBERSHIP_USER_DATA)HeapAlloc(GetProcessHeap(),
417 HEAP_ZERO_MEMORY,
418 sizeof(MEMBERSHIP_USER_DATA) +
419 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
420 lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
421
422 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
423
424 GetUserMembershipData(hwndDlg, pUserData);
425 break;
426
427 case WM_COMMAND:
428 switch (LOWORD(wParam))
429 {
430 case IDC_USER_MEMBERSHIP_REMOVE:
431 RemoveGroupFromUser(hwndDlg, pUserData);
432 break;
433 }
434 break;
435
436 case WM_NOTIFY:
437 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
438 {
439 return TRUE;
440 }
441 else
442 {
443 return OnNotify(hwndDlg, pUserData, lParam);
444 }
445 break;
446
447
448 case WM_DESTROY:
449 if (pUserData->pGroupData)
450 NetApiBufferFree(pUserData->pGroupData);
451
452 HeapFree(GetProcessHeap(), 0, pUserData);
453 break;
454 }
455
456 return FALSE;
457 }
458
459
460 static VOID
461 UpdateUserOptions(HWND hwndDlg,
462 PGENERAL_USER_DATA pUserData,
463 BOOL bInit)
464 {
465 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE),
466 !pUserData->dwPasswordExpired);
467 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES),
468 !pUserData->dwPasswordExpired);
469 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE),
470 (pUserData->dwFlags & (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD)) == 0);
471
472 EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_LOCKED),
473 (pUserData->dwFlags & UF_LOCKOUT) != 0);
474
475 if (bInit)
476 {
477 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE,
478 pUserData->dwPasswordExpired ? BST_CHECKED : BST_UNCHECKED);
479
480 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE,
481 (pUserData->dwFlags & UF_PASSWD_CANT_CHANGE) ? BST_CHECKED : BST_UNCHECKED);
482
483 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES,
484 (pUserData->dwFlags & UF_DONT_EXPIRE_PASSWD) ? BST_CHECKED : BST_UNCHECKED);
485
486 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_DISABLED,
487 (pUserData->dwFlags & UF_ACCOUNTDISABLE) ? BST_CHECKED : BST_UNCHECKED);
488
489 CheckDlgButton(hwndDlg, IDC_USER_GENERAL_LOCKED,
490 (pUserData->dwFlags & UF_LOCKOUT) ? BST_CHECKED : BST_UNCHECKED);
491 }
492 }
493
494
495 static VOID
496 GetUserGeneralData(HWND hwndDlg,
497 PGENERAL_USER_DATA pUserData)
498 {
499 PUSER_INFO_3 pUserInfo = NULL;
500
501 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_NAME, pUserData->szUserName);
502
503 NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
504
505 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, pUserInfo->usri3_full_name);
506 SetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, pUserInfo->usri3_comment);
507
508 pUserData->dwFlags = pUserInfo->usri3_flags;
509 pUserData->dwPasswordExpired = pUserInfo->usri3_password_expired;
510
511 NetApiBufferFree(pUserInfo);
512
513 UpdateUserOptions(hwndDlg, pUserData, TRUE);
514 }
515
516
517 static BOOL
518 SetUserGeneralData(HWND hwndDlg,
519 PGENERAL_USER_DATA pUserData)
520 {
521 PUSER_INFO_3 pUserInfo = NULL;
522 LPTSTR pszFullName = NULL;
523 LPTSTR pszComment = NULL;
524 NET_API_STATUS status;
525 #if 0
526 DWORD dwIndex;
527 #endif
528 INT nLength;
529
530 NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
531
532 pUserInfo->usri3_flags =
533 (pUserData->dwFlags & VALID_GENERAL_FLAGS) |
534 (pUserInfo->usri3_flags & ~VALID_GENERAL_FLAGS);
535
536 pUserInfo->usri3_password_expired = pUserData->dwPasswordExpired;
537
538 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FULL_NAME));
539 if (nLength == 0)
540 {
541 pUserInfo->usri3_full_name = NULL;
542 }
543 else
544 {
545 pszFullName = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
546 GetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, pszFullName, nLength + 1);
547 pUserInfo->usri3_full_name = pszFullName;
548 }
549
550 nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_GENERAL_DESCRIPTION));
551 if (nLength == 0)
552 {
553 pUserInfo->usri3_full_name = NULL;
554 }
555 else
556 {
557 pszComment = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
558 GetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, pszComment, nLength + 1);
559 pUserInfo->usri3_comment = pszComment;
560 }
561
562 #if 0
563 status = NetUserSetInfo(NULL, pUserData->szUserName, 3, (LPBYTE)pUserInfo, &dwIndex);
564 if (status != NERR_Success)
565 {
566 DebugPrintf(_T("Status: %lu Index: %lu"), status, dwIndex);
567 }
568 #else
569 status = NERR_Success;
570 #endif
571
572 if (pszFullName)
573 HeapFree(GetProcessHeap(), 0, pszFullName);
574
575 if (pszComment)
576 HeapFree(GetProcessHeap(), 0, pszComment);
577
578 NetApiBufferFree(pUserInfo);
579
580 return (status == NERR_Success);
581 }
582
583
584 INT_PTR CALLBACK
585 UserGeneralPageProc(HWND hwndDlg,
586 UINT uMsg,
587 WPARAM wParam,
588 LPARAM lParam)
589 {
590 PGENERAL_USER_DATA pUserData;
591
592 UNREFERENCED_PARAMETER(lParam);
593 UNREFERENCED_PARAMETER(wParam);
594 UNREFERENCED_PARAMETER(hwndDlg);
595
596 pUserData= (PGENERAL_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
597
598 switch (uMsg)
599 {
600 case WM_INITDIALOG:
601 pUserData = (PGENERAL_USER_DATA)HeapAlloc(GetProcessHeap(),
602 HEAP_ZERO_MEMORY,
603 sizeof(GENERAL_USER_DATA) +
604 lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
605 lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
606
607 SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
608
609 GetUserGeneralData(hwndDlg,
610 pUserData);
611 break;
612
613 case WM_COMMAND:
614 switch (LOWORD(wParam))
615 {
616 case IDC_USER_GENERAL_FULL_NAME:
617 case IDC_USER_GENERAL_DESCRIPTION:
618 if (HIWORD(wParam) == EN_CHANGE)
619 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
620 break;
621
622 case IDC_USER_GENERAL_FORCE_CHANGE:
623 pUserData->dwPasswordExpired = !pUserData->dwPasswordExpired;
624 UpdateUserOptions(hwndDlg, pUserData, FALSE);
625 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
626 break;
627
628 case IDC_USER_GENERAL_CANNOT_CHANGE:
629 pUserData->dwFlags ^= UF_PASSWD_CANT_CHANGE;
630 UpdateUserOptions(hwndDlg, pUserData, FALSE);
631 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
632 break;
633
634 case IDC_USER_GENERAL_NEVER_EXPIRES:
635 pUserData->dwFlags ^= UF_DONT_EXPIRE_PASSWD;
636 UpdateUserOptions(hwndDlg, pUserData, FALSE);
637 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
638 break;
639
640 case IDC_USER_GENERAL_DISABLED:
641 pUserData->dwFlags ^= UF_ACCOUNTDISABLE;
642 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
643 break;
644
645 case IDC_USER_GENERAL_LOCKED:
646 pUserData->dwFlags ^= UF_LOCKOUT;
647 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
648 break;
649 }
650 break;
651
652 case WM_NOTIFY:
653 if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
654 {
655 SetUserGeneralData(hwndDlg, pUserData);
656 return TRUE;
657 }
658 break;
659
660 case WM_DESTROY:
661 HeapFree(GetProcessHeap(), 0, pUserData);
662 break;
663 }
664
665 return FALSE;
666 }
667
668
669 static VOID
670 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPTSTR pszUser)
671 {
672 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
673 psp->dwSize = sizeof(PROPSHEETPAGE);
674 psp->dwFlags = PSP_DEFAULT;
675 psp->hInstance = hApplet;
676 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
677 psp->pfnDlgProc = DlgProc;
678 psp->lParam = (LPARAM)pszUser;
679 }
680
681
682 BOOL
683 UserProperties(HWND hwndDlg)
684 {
685 PROPSHEETPAGE psp[3];
686 PROPSHEETHEADER psh;
687 TCHAR szUserName[UNLEN];
688 INT nItem;
689 HWND hwndLV;
690
691 hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
692 nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
693 if (nItem == -1)
694 return FALSE;
695
696 /* Get the new user name */
697 ListView_GetItemText(hwndLV,
698 nItem, 0,
699 szUserName,
700 UNLEN);
701
702 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
703 psh.dwSize = sizeof(PROPSHEETHEADER);
704 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
705 psh.hwndParent = hwndDlg;
706 psh.hInstance = hApplet;
707 psh.hIcon = NULL;
708 psh.pszCaption = szUserName;
709 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
710 psh.nStartPage = 0;
711 psh.ppsp = psp;
712
713 InitPropSheetPage(&psp[0], IDD_USER_GENERAL, (DLGPROC)UserGeneralPageProc, szUserName);
714 InitPropSheetPage(&psp[1], IDD_USER_MEMBERSHIP, (DLGPROC)UserMembershipPageProc, szUserName);
715 InitPropSheetPage(&psp[2], IDD_USER_PROFILE, (DLGPROC)UserProfilePageProc, szUserName);
716
717 return (PropertySheet(&psh) == IDOK);
718 }