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
7 * PROGRAMMERS: Eric Kohl
12 typedef struct _GENERAL_USER_DATA
15 DWORD dwPasswordExpired
;
17 } GENERAL_USER_DATA
, *PGENERAL_USER_DATA
;
19 #define VALID_GENERAL_FLAGS (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD | UF_ACCOUNTDISABLE | UF_LOCKOUT)
21 typedef struct _PROFILE_USER_DATA
24 } PROFILE_USER_DATA
, *PPROFILE_USER_DATA
;
29 GetUserProfileData(HWND hwndDlg
,
30 PPROFILE_USER_DATA pUserData
)
32 PUSER_INFO_3 userInfo
= NULL
;
33 NET_API_STATUS status
;
39 status
= NetUserGetInfo(NULL
, pUserData
->szUserName
, 3, (LPBYTE
*)&userInfo
);
40 if (status
!= NERR_Success
)
43 SetDlgItemText(hwndDlg
, IDC_USER_PROFILE_PATH
, userInfo
->usri3_profile
);
44 SetDlgItemText(hwndDlg
, IDC_USER_PROFILE_SCRIPT
, userInfo
->usri3_script_path
);
47 bLocal
= (userInfo
->usri3_home_dir_drive
== NULL
) ||
48 (_tcslen(userInfo
->usri3_home_dir_drive
) == 0);
49 CheckRadioButton(hwndDlg
, IDC_USER_PROFILE_LOCAL
, IDC_USER_PROFILE_REMOTE
,
50 bLocal
? IDC_USER_PROFILE_LOCAL
: IDC_USER_PROFILE_REMOTE
);
52 for (i
= 0; i
< 26; i
++)
54 wsprintf(szDrive
, _T("%c:"), (TCHAR
)('A' + i
));
55 nSel
= SendMessage(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
),
56 CB_INSERTSTRING
, -1, (LPARAM
)szDrive
);
61 SetDlgItemText(hwndDlg
, IDC_USER_PROFILE_LOCAL_PATH
, userInfo
->usri3_home_dir
);
62 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
), FALSE
);
63 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_REMOTE_PATH
), FALSE
);
67 SetDlgItemText(hwndDlg
, IDC_USER_PROFILE_REMOTE_PATH
, userInfo
->usri3_home_dir
);
68 nSel
= SendMessage(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
),
69 CB_FINDSTRINGEXACT
, -1, (LPARAM
)userInfo
->usri3_home_dir_drive
);
72 SendMessage(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
),
73 CB_SETCURSEL
, nSel
, 0);
75 NetApiBufferFree(userInfo
);
80 SetUserProfileData(HWND hwndDlg
,
81 PPROFILE_USER_DATA pUserData
)
83 PUSER_INFO_3 pUserInfo
= NULL
;
84 LPTSTR pszProfilePath
= NULL
;
85 LPTSTR pszScriptPath
= NULL
;
86 LPTSTR pszHomeDir
= NULL
;
87 LPTSTR pszHomeDrive
= NULL
;
88 NET_API_STATUS status
;
95 NetUserGetInfo(NULL
, pUserData
->szUserName
, 3, (LPBYTE
*)&pUserInfo
);
97 /* Get the profile path */
98 nLength
= GetWindowTextLength(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_PATH
));
101 pUserInfo
->usri3_profile
= NULL
;
105 pszProfilePath
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(TCHAR
));
106 GetDlgItemText(hwndDlg
, IDC_USER_PROFILE_PATH
, pszProfilePath
, nLength
+ 1);
107 pUserInfo
->usri3_profile
= pszProfilePath
;
110 /* Get the script path */
111 nLength
= GetWindowTextLength(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_SCRIPT
));
114 pUserInfo
->usri3_script_path
= NULL
;
118 pszScriptPath
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(TCHAR
));
119 GetDlgItemText(hwndDlg
, IDC_USER_PROFILE_SCRIPT
, pszScriptPath
, nLength
+ 1);
120 pUserInfo
->usri3_script_path
= pszScriptPath
;
123 if (IsDlgButtonChecked(hwndDlg
, IDC_USER_PROFILE_LOCAL
) == BST_CHECKED
)
125 /* Local home directory */
126 nLength
= GetWindowTextLength(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_LOCAL_PATH
));
129 pUserInfo
->usri3_home_dir
= NULL
;
133 pszHomeDir
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(TCHAR
));
134 GetDlgItemText(hwndDlg
, IDC_USER_PROFILE_LOCAL_PATH
, pszHomeDir
, nLength
+ 1);
135 pUserInfo
->usri3_home_dir
= pszHomeDir
;
140 /* Remote home directory */
141 nLength
= GetWindowTextLength(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_REMOTE_PATH
));
144 pUserInfo
->usri3_home_dir
= NULL
;
148 pszHomeDir
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(TCHAR
));
149 GetDlgItemText(hwndDlg
, IDC_USER_PROFILE_REMOTE_PATH
, pszHomeDir
, nLength
+ 1);
150 pUserInfo
->usri3_home_dir
= pszHomeDir
;
153 nIndex
= SendMessage(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
), CB_GETCURSEL
, 0, 0);
154 if (nIndex
!= CB_ERR
)
156 nLength
= SendMessage(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
), CB_GETLBTEXTLEN
, nIndex
, 0);
157 pszHomeDrive
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(TCHAR
));
158 SendMessage(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
), CB_GETLBTEXT
, nIndex
, (LPARAM
)pszHomeDrive
);
159 pUserInfo
->usri3_home_dir_drive
= pszHomeDrive
;
164 status
= NetUserSetInfo(NULL
, pUserData
->szUserName
, 3, (LPBYTE
)pUserInfo
, &dwIndex
);
165 if (status
!= NERR_Success
)
167 DebugPrintf(_T("Status: %lu Index: %lu"), status
, dwIndex
);
170 status
= NERR_Success
;
174 HeapFree(GetProcessHeap(), 0, pszProfilePath
);
177 HeapFree(GetProcessHeap(), 0, pszScriptPath
);
180 HeapFree(GetProcessHeap(), 0, pszHomeDir
);
183 HeapFree(GetProcessHeap(), 0, pszHomeDrive
);
185 NetApiBufferFree(pUserInfo
);
187 return (status
== NERR_Success
);
192 UserProfilePageProc(HWND hwndDlg
,
197 PPROFILE_USER_DATA pUserData
;
199 UNREFERENCED_PARAMETER(lParam
);
200 UNREFERENCED_PARAMETER(wParam
);
201 UNREFERENCED_PARAMETER(hwndDlg
);
203 pUserData
= (PPROFILE_USER_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
208 pUserData
= (PPROFILE_USER_DATA
)HeapAlloc(GetProcessHeap(),
210 sizeof(PROFILE_USER_DATA
) +
211 lstrlen((LPTSTR
)((PROPSHEETPAGE
*)lParam
)->lParam
) * sizeof(TCHAR
));
212 lstrcpy(pUserData
->szUserName
, (LPTSTR
)((PROPSHEETPAGE
*)lParam
)->lParam
);
214 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (INT_PTR
)pUserData
);
216 GetUserProfileData(hwndDlg
,
221 switch (LOWORD(wParam
))
223 case IDC_USER_PROFILE_PATH
:
224 case IDC_USER_PROFILE_SCRIPT
:
225 if (HIWORD(wParam
) == EN_CHANGE
)
226 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
229 case IDC_USER_PROFILE_LOCAL
:
230 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_LOCAL_PATH
), TRUE
);
231 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
), FALSE
);
232 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_REMOTE_PATH
), FALSE
);
235 case IDC_USER_PROFILE_REMOTE
:
236 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_LOCAL_PATH
), FALSE
);
237 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_DRIVE
), TRUE
);
238 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_PROFILE_REMOTE_PATH
), TRUE
);
244 HeapFree(GetProcessHeap(), 0, pUserData
);
248 if (((LPPSHNOTIFY
)lParam
)->hdr
.code
== PSN_APPLY
)
250 SetUserProfileData(hwndDlg
, pUserData
);
261 GetMembershipData(HWND hwndDlg
, LPTSTR lpUserName
)
263 PLOCALGROUP_USERS_INFO_0 usersInfo
= NULL
;
264 NET_API_STATUS status
;
276 hwndLV
= GetDlgItem(hwndDlg
, IDC_USER_MEMBERSHIP_LIST
);
278 /* Create the image list */
279 hImgList
= ImageList_Create(16, 16, ILC_COLOR8
| ILC_MASK
, 5, 5);
280 hIcon
= LoadImage(hApplet
, MAKEINTRESOURCE(IDI_GROUP
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
281 ImageList_AddIcon(hImgList
, hIcon
);
283 (void)ListView_SetImageList(hwndLV
, hImgList
, LVSIL_SMALL
);
285 /* Set the list column */
286 GetClientRect(hwndLV
, &rect
);
288 memset(&column
, 0x00, sizeof(column
));
289 column
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_SUBITEM
;
290 column
.fmt
= LVCFMT_LEFT
;
291 column
.cx
= (INT
)(rect
.right
- rect
.left
);
293 (void)ListView_InsertColumn(hwndLV
, 0, &column
);
296 status
= NetUserGetLocalGroups(NULL
, lpUserName
, 0, 0,
298 MAX_PREFERRED_LENGTH
,
301 if (status
!= NERR_Success
)
304 for (i
= 0; i
< dwRead
; i
++)
306 ZeroMemory(&lvi
, sizeof(lvi
));
307 lvi
.mask
= LVIF_TEXT
| LVIF_STATE
| LVIF_IMAGE
;
308 lvi
.pszText
= usersInfo
[i
].lgrui0_name
;
312 (void)ListView_InsertItem(hwndLV
, &lvi
);
316 NetApiBufferFree(usersInfo
);
322 UserMembershipPageProc(HWND hwndDlg
,
328 UNREFERENCED_PARAMETER(lParam
);
329 UNREFERENCED_PARAMETER(wParam
);
330 UNREFERENCED_PARAMETER(hwndDlg
);
335 GetMembershipData(hwndDlg
,
336 (LPTSTR
)((PROPSHEETPAGE
*)lParam
)->lParam
);
346 UpdateUserOptions(HWND hwndDlg
,
347 PGENERAL_USER_DATA pUserData
,
350 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_GENERAL_CANNOT_CHANGE
),
351 !pUserData
->dwPasswordExpired
);
352 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_GENERAL_NEVER_EXPIRES
),
353 !pUserData
->dwPasswordExpired
);
354 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_GENERAL_FORCE_CHANGE
),
355 (pUserData
->dwFlags
& (UF_PASSWD_CANT_CHANGE
| UF_DONT_EXPIRE_PASSWD
)) == 0);
357 EnableWindow(GetDlgItem(hwndDlg
, IDC_USER_GENERAL_LOCKED
),
358 (pUserData
->dwFlags
& UF_LOCKOUT
) != 0);
362 CheckDlgButton(hwndDlg
, IDC_USER_GENERAL_FORCE_CHANGE
,
363 pUserData
->dwPasswordExpired
? BST_CHECKED
: BST_UNCHECKED
);
365 CheckDlgButton(hwndDlg
, IDC_USER_GENERAL_CANNOT_CHANGE
,
366 (pUserData
->dwFlags
& UF_PASSWD_CANT_CHANGE
) ? BST_CHECKED
: BST_UNCHECKED
);
368 CheckDlgButton(hwndDlg
, IDC_USER_GENERAL_NEVER_EXPIRES
,
369 (pUserData
->dwFlags
& UF_DONT_EXPIRE_PASSWD
) ? BST_CHECKED
: BST_UNCHECKED
);
371 CheckDlgButton(hwndDlg
, IDC_USER_GENERAL_DISABLED
,
372 (pUserData
->dwFlags
& UF_ACCOUNTDISABLE
) ? BST_CHECKED
: BST_UNCHECKED
);
374 CheckDlgButton(hwndDlg
, IDC_USER_GENERAL_LOCKED
,
375 (pUserData
->dwFlags
& UF_LOCKOUT
) ? BST_CHECKED
: BST_UNCHECKED
);
381 GetUserGeneralData(HWND hwndDlg
,
382 PGENERAL_USER_DATA pUserData
)
384 PUSER_INFO_3 pUserInfo
= NULL
;
386 SetDlgItemText(hwndDlg
, IDC_USER_GENERAL_NAME
, pUserData
->szUserName
);
388 NetUserGetInfo(NULL
, pUserData
->szUserName
, 3, (LPBYTE
*)&pUserInfo
);
390 SetDlgItemText(hwndDlg
, IDC_USER_GENERAL_FULL_NAME
, pUserInfo
->usri3_full_name
);
391 SetDlgItemText(hwndDlg
, IDC_USER_GENERAL_DESCRIPTION
, pUserInfo
->usri3_comment
);
393 pUserData
->dwFlags
= pUserInfo
->usri3_flags
;
394 pUserData
->dwPasswordExpired
= pUserInfo
->usri3_password_expired
;
396 NetApiBufferFree(pUserInfo
);
398 UpdateUserOptions(hwndDlg
, pUserData
, TRUE
);
403 SetUserGeneralData(HWND hwndDlg
,
404 PGENERAL_USER_DATA pUserData
)
406 PUSER_INFO_3 pUserInfo
= NULL
;
407 LPTSTR pszFullName
= NULL
;
408 LPTSTR pszComment
= NULL
;
409 NET_API_STATUS status
;
415 NetUserGetInfo(NULL
, pUserData
->szUserName
, 3, (LPBYTE
*)&pUserInfo
);
417 pUserInfo
->usri3_flags
=
418 (pUserData
->dwFlags
& VALID_GENERAL_FLAGS
) |
419 (pUserInfo
->usri3_flags
& ~VALID_GENERAL_FLAGS
);
421 pUserInfo
->usri3_password_expired
= pUserData
->dwPasswordExpired
;
423 nLength
= GetWindowTextLength(GetDlgItem(hwndDlg
, IDC_USER_GENERAL_FULL_NAME
));
426 pUserInfo
->usri3_full_name
= NULL
;
430 pszFullName
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(TCHAR
));
431 GetDlgItemText(hwndDlg
, IDC_USER_GENERAL_FULL_NAME
, pszFullName
, nLength
+ 1);
432 pUserInfo
->usri3_full_name
= pszFullName
;
435 nLength
= GetWindowTextLength(GetDlgItem(hwndDlg
, IDC_USER_GENERAL_DESCRIPTION
));
438 pUserInfo
->usri3_full_name
= NULL
;
442 pszComment
= HeapAlloc(GetProcessHeap(), 0, (nLength
+ 1) * sizeof(TCHAR
));
443 GetDlgItemText(hwndDlg
, IDC_USER_GENERAL_DESCRIPTION
, pszComment
, nLength
+ 1);
444 pUserInfo
->usri3_comment
= pszComment
;
448 status
= NetUserSetInfo(NULL
, pUserData
->szUserName
, 3, (LPBYTE
)pUserInfo
, &dwIndex
);
449 if (status
!= NERR_Success
)
451 DebugPrintf(_T("Status: %lu Index: %lu"), status
, dwIndex
);
454 status
= NERR_Success
;
458 HeapFree(GetProcessHeap(), 0, pszFullName
);
461 HeapFree(GetProcessHeap(), 0, pszComment
);
463 NetApiBufferFree(pUserInfo
);
465 return (status
== NERR_Success
);
470 UserGeneralPageProc(HWND hwndDlg
,
475 PGENERAL_USER_DATA pUserData
;
477 UNREFERENCED_PARAMETER(lParam
);
478 UNREFERENCED_PARAMETER(wParam
);
479 UNREFERENCED_PARAMETER(hwndDlg
);
481 pUserData
= (PGENERAL_USER_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
486 pUserData
= (PGENERAL_USER_DATA
)HeapAlloc(GetProcessHeap(),
488 sizeof(GENERAL_USER_DATA
) +
489 lstrlen((LPTSTR
)((PROPSHEETPAGE
*)lParam
)->lParam
) * sizeof(TCHAR
));
490 lstrcpy(pUserData
->szUserName
, (LPTSTR
)((PROPSHEETPAGE
*)lParam
)->lParam
);
492 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (INT_PTR
)pUserData
);
494 GetUserGeneralData(hwndDlg
,
499 switch (LOWORD(wParam
))
501 case IDC_USER_GENERAL_FULL_NAME
:
502 case IDC_USER_GENERAL_DESCRIPTION
:
503 if (HIWORD(wParam
) == EN_CHANGE
)
504 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
507 case IDC_USER_GENERAL_FORCE_CHANGE
:
508 pUserData
->dwPasswordExpired
= !pUserData
->dwPasswordExpired
;
509 UpdateUserOptions(hwndDlg
, pUserData
, FALSE
);
510 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
513 case IDC_USER_GENERAL_CANNOT_CHANGE
:
514 pUserData
->dwFlags
^= UF_PASSWD_CANT_CHANGE
;
515 UpdateUserOptions(hwndDlg
, pUserData
, FALSE
);
516 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
519 case IDC_USER_GENERAL_NEVER_EXPIRES
:
520 pUserData
->dwFlags
^= UF_DONT_EXPIRE_PASSWD
;
521 UpdateUserOptions(hwndDlg
, pUserData
, FALSE
);
522 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
525 case IDC_USER_GENERAL_DISABLED
:
526 pUserData
->dwFlags
^= UF_ACCOUNTDISABLE
;
527 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
530 case IDC_USER_GENERAL_LOCKED
:
531 pUserData
->dwFlags
^= UF_LOCKOUT
;
532 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
538 if (((LPPSHNOTIFY
)lParam
)->hdr
.code
== PSN_APPLY
)
540 SetUserGeneralData(hwndDlg
, pUserData
);
546 HeapFree(GetProcessHeap(), 0, pUserData
);
555 InitPropSheetPage(PROPSHEETPAGE
*psp
, WORD idDlg
, DLGPROC DlgProc
, LPTSTR pszUser
)
557 ZeroMemory(psp
, sizeof(PROPSHEETPAGE
));
558 psp
->dwSize
= sizeof(PROPSHEETPAGE
);
559 psp
->dwFlags
= PSP_DEFAULT
;
560 psp
->hInstance
= hApplet
;
561 psp
->pszTemplate
= MAKEINTRESOURCE(idDlg
);
562 psp
->pfnDlgProc
= DlgProc
;
563 psp
->lParam
= (LPARAM
)pszUser
;
568 UserProperties(HWND hwndDlg
)
570 PROPSHEETPAGE psp
[3];
572 TCHAR szUserName
[UNLEN
];
576 hwndLV
= GetDlgItem(hwndDlg
, IDC_USERS_LIST
);
577 nItem
= ListView_GetNextItem(hwndLV
, -1, LVNI_SELECTED
);
581 /* Get the new user name */
582 ListView_GetItemText(hwndLV
,
587 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
588 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
589 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_PROPTITLE
;
590 psh
.hwndParent
= hwndDlg
;
591 psh
.hInstance
= hApplet
;
593 psh
.pszCaption
= szUserName
;
594 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
598 InitPropSheetPage(&psp
[0], IDD_USER_GENERAL
, (DLGPROC
)UserGeneralPageProc
, szUserName
);
599 InitPropSheetPage(&psp
[1], IDD_USER_MEMBERSHIP
, (DLGPROC
)UserMembershipPageProc
, szUserName
);
600 InitPropSheetPage(&psp
[2], IDD_USER_PROFILE
, (DLGPROC
)UserProfilePageProc
, szUserName
);
602 return (PropertySheet(&psh
) == IDOK
);