reactos/dll/cpl/usrmgr/userprops.c
2017-12-25 22:11:57 +01:00

937 lines
29 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS User Manager Control Panel
* FILE: dll/cpl/usrmgr/userprops.c
* PURPOSE: User property sheet
*
* PROGRAMMERS: Eric Kohl
*/
#include "usrmgr.h"
typedef struct _GENERAL_USER_DATA
{
DWORD dwFlags;
DWORD dwPasswordExpired;
TCHAR szUserName[1];
} GENERAL_USER_DATA, *PGENERAL_USER_DATA;
#define VALID_GENERAL_FLAGS (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD | UF_ACCOUNTDISABLE | UF_LOCKOUT)
typedef struct _PROFILE_USER_DATA
{
TCHAR szUserName[1];
} PROFILE_USER_DATA, *PPROFILE_USER_DATA;
typedef struct _MEMBERSHIP_USER_DATA
{
PLOCALGROUP_USERS_INFO_0 pGroupData;
DWORD dwGroupCount;
TCHAR szUserName[1];
} MEMBERSHIP_USER_DATA, *PMEMBERSHIP_USER_DATA;
static VOID
GetUserProfileData(HWND hwndDlg,
PPROFILE_USER_DATA pUserData)
{
PUSER_INFO_3 userInfo = NULL;
NET_API_STATUS status;
BOOL bLocal;
TCHAR szDrive[8];
INT i;
INT nSel;
status = NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&userInfo);
if (status != NERR_Success)
return;
SetDlgItemText(hwndDlg, IDC_USER_PROFILE_PATH, userInfo->usri3_profile);
SetDlgItemText(hwndDlg, IDC_USER_PROFILE_SCRIPT, userInfo->usri3_script_path);
bLocal = (userInfo->usri3_home_dir_drive == NULL) ||
(_tcslen(userInfo->usri3_home_dir_drive) == 0);
CheckRadioButton(hwndDlg, IDC_USER_PROFILE_LOCAL, IDC_USER_PROFILE_REMOTE,
bLocal ? IDC_USER_PROFILE_LOCAL : IDC_USER_PROFILE_REMOTE);
for (i = 0; i < 26; i++)
{
wsprintf(szDrive, _T("%c:"), (TCHAR)('A' + i));
nSel = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
CB_INSERTSTRING, -1, (LPARAM)szDrive);
}
if (bLocal)
{
SetDlgItemText(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH, userInfo->usri3_home_dir);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), FALSE);
}
else
{
SetDlgItemText(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH, userInfo->usri3_home_dir);
nSel = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
CB_FINDSTRINGEXACT, -1, (LPARAM)userInfo->usri3_home_dir_drive);
}
SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE),
CB_SETCURSEL, nSel, 0);
NetApiBufferFree(userInfo);
}
static BOOL
SetUserProfileData(HWND hwndDlg,
PPROFILE_USER_DATA pUserData)
{
PUSER_INFO_3 pUserInfo = NULL;
LPTSTR pszProfilePath = NULL;
LPTSTR pszScriptPath = NULL;
LPTSTR pszHomeDir = NULL;
LPTSTR pszHomeDrive = NULL;
NET_API_STATUS status;
DWORD dwIndex;
INT nLength;
INT nIndex;
NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
/* Get the profile path */
nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_PATH));
if (nLength == 0)
{
pUserInfo->usri3_profile = NULL;
}
else
{
pszProfilePath = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
GetDlgItemText(hwndDlg, IDC_USER_PROFILE_PATH, pszProfilePath, nLength + 1);
pUserInfo->usri3_profile = pszProfilePath;
}
/* Get the script path */
nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_SCRIPT));
if (nLength == 0)
{
pUserInfo->usri3_script_path = NULL;
}
else
{
pszScriptPath = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
GetDlgItemText(hwndDlg, IDC_USER_PROFILE_SCRIPT, pszScriptPath, nLength + 1);
pUserInfo->usri3_script_path = pszScriptPath;
}
if (IsDlgButtonChecked(hwndDlg, IDC_USER_PROFILE_LOCAL) == BST_CHECKED)
{
/* Local home directory */
nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH));
if (nLength == 0)
{
pUserInfo->usri3_home_dir = NULL;
}
else
{
pszHomeDir = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
GetDlgItemText(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH, pszHomeDir, nLength + 1);
pUserInfo->usri3_home_dir = pszHomeDir;
}
}
else
{
/* Remote home directory */
nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH));
if (nLength == 0)
{
pUserInfo->usri3_home_dir = NULL;
}
else
{
pszHomeDir = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
GetDlgItemText(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH, pszHomeDir, nLength + 1);
pUserInfo->usri3_home_dir = pszHomeDir;
}
nIndex = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETCURSEL, 0, 0);
if (nIndex != CB_ERR)
{
nLength = SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETLBTEXTLEN, nIndex, 0);
pszHomeDrive = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
SendMessage(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), CB_GETLBTEXT, nIndex, (LPARAM)pszHomeDrive);
pUserInfo->usri3_home_dir_drive = pszHomeDrive;
}
}
status = NetUserSetInfo(NULL, pUserData->szUserName, 3, (LPBYTE)pUserInfo, &dwIndex);
if (status != NERR_Success)
{
DebugPrintf(_T("Status: %lu Index: %lu"), status, dwIndex);
}
if (pszProfilePath)
HeapFree(GetProcessHeap(), 0, pszProfilePath);
if (pszScriptPath)
HeapFree(GetProcessHeap(), 0, pszScriptPath);
if (pszHomeDir)
HeapFree(GetProcessHeap(), 0, pszHomeDir);
if (pszHomeDrive)
HeapFree(GetProcessHeap(), 0, pszHomeDrive);
NetApiBufferFree(pUserInfo);
return (status == NERR_Success);
}
INT_PTR CALLBACK
UserProfilePageProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PPROFILE_USER_DATA pUserData;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(hwndDlg);
pUserData= (PPROFILE_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch (uMsg)
{
case WM_INITDIALOG:
pUserData = (PPROFILE_USER_DATA)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(PROFILE_USER_DATA) +
lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
GetUserProfileData(hwndDlg,
pUserData);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_USER_PROFILE_PATH:
case IDC_USER_PROFILE_SCRIPT:
if (HIWORD(wParam) == EN_CHANGE)
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
case IDC_USER_PROFILE_LOCAL:
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), FALSE);
break;
case IDC_USER_PROFILE_REMOTE:
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_LOCAL_PATH), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_DRIVE), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_PROFILE_REMOTE_PATH), TRUE);
break;
}
break;
case WM_DESTROY:
HeapFree(GetProcessHeap(), 0, pUserData);
break;
case WM_NOTIFY:
if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
{
SetUserProfileData(hwndDlg, pUserData);
return TRUE;
}
break;
}
return FALSE;
}
static VOID
GetUserMembershipData(HWND hwndDlg, PMEMBERSHIP_USER_DATA pUserData)
{
NET_API_STATUS status;
DWORD dwTotal;
DWORD i;
HIMAGELIST hImgList;
HICON hIcon;
LV_ITEM lvi;
HWND hwndLV;
LV_COLUMN column;
RECT rect;
hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
/* Create the image list */
hImgList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 5, 5);
hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_GROUP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
ImageList_AddIcon(hImgList, hIcon);
DestroyIcon(hIcon);
(void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
/* Set the list column */
GetClientRect(hwndLV, &rect);
memset(&column, 0x00, sizeof(column));
column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
column.fmt = LVCFMT_LEFT;
column.cx = (INT)(rect.right - rect.left);
column.iSubItem = 0;
(void)ListView_InsertColumn(hwndLV, 0, &column);
status = NetUserGetLocalGroups(NULL, pUserData->szUserName, 0, 0,
(LPBYTE*)&pUserData->pGroupData,
MAX_PREFERRED_LENGTH,
&pUserData->dwGroupCount,
&dwTotal);
if (status != NERR_Success)
return;
for (i = 0; i < pUserData->dwGroupCount; i++)
{
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
lvi.pszText = pUserData->pGroupData[i].lgrui0_name;
lvi.state = 0;
lvi.iImage = 0;
(void)ListView_InsertItem(hwndLV, &lvi);
}
}
static VOID
RemoveGroupFromUser(HWND hwndDlg,
PMEMBERSHIP_USER_DATA pUserData)
{
TCHAR szGroupName[UNLEN];
TCHAR szText[256];
LOCALGROUP_MEMBERS_INFO_3 memberInfo;
HWND hwndLV;
INT nItem;
NET_API_STATUS status;
hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
if (nItem == -1)
return;
/* Get the new user name */
ListView_GetItemText(hwndLV,
nItem, 0,
szGroupName,
UNLEN);
/* Display a warning message because the remove operation cannot be reverted */
wsprintf(szText, TEXT("Do you really want to remove the user \"%s\" from the group \"%s\"?"),
pUserData->szUserName, szGroupName);
if (MessageBox(NULL, szText, TEXT("User Accounts"), MB_ICONWARNING | MB_YESNO) == IDNO)
return;
memberInfo.lgrmi3_domainandname = pUserData->szUserName;
status = NetLocalGroupDelMembers(NULL, szGroupName,
3, (LPBYTE)&memberInfo, 1);
if (status != NERR_Success)
{
TCHAR szText[256];
wsprintf(szText, TEXT("Error: %u"), status);
MessageBox(NULL, szText, TEXT("NetLocalGroupDelMembers"), MB_ICONERROR | MB_OK);
return;
}
(void)ListView_DeleteItem(hwndLV, nItem);
if (ListView_GetItemCount(hwndLV) == 0)
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_REMOVE), FALSE);
}
static VOID
InitUserGroupsList(HWND hwndDlg)
{
HWND hwndLV;
LV_COLUMN column;
RECT rect;
TCHAR szStr[32];
NET_API_STATUS netStatus;
PLOCALGROUP_INFO_1 pBuffer;
DWORD entriesread;
DWORD totalentries;
DWORD_PTR resume_handle = 0;
DWORD i;
LV_ITEM lvi;
INT iItem;
HIMAGELIST hImgList;
HICON hIcon;
hwndLV = GetDlgItem(hwndDlg, IDC_USER_ADD_MEMBERSHIP_LIST);
GetClientRect(hwndLV, &rect);
hImgList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 5, 5);
hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_GROUP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
ImageList_AddIcon(hImgList, hIcon);
DestroyIcon(hIcon);
(void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL);
(void)ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
memset(&column, 0x00, sizeof(column));
column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_TEXT;
column.fmt = LVCFMT_LEFT;
column.cx = (INT)((rect.right - rect.left) * 0.40);
column.iSubItem = 0;
LoadString(hApplet, IDS_NAME, szStr, sizeof(szStr) / sizeof(szStr[0]));
column.pszText = szStr;
(void)ListView_InsertColumn(hwndLV, 0, &column);
column.cx = (INT)((rect.right - rect.left) * 0.60);
column.iSubItem = 1;
LoadString(hApplet, IDS_DESCRIPTION, szStr, sizeof(szStr) / sizeof(szStr[0]));
column.pszText = szStr;
(void)ListView_InsertColumn(hwndLV, 1, &column);
for (;;)
{
netStatus = NetLocalGroupEnum(NULL, 1, (LPBYTE*)&pBuffer,
1024, &entriesread,
&totalentries, &resume_handle);
if (netStatus != NERR_Success && netStatus != ERROR_MORE_DATA)
break;
for (i = 0; i < entriesread; i++)
{
memset(&lvi, 0x00, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
lvi.pszText = pBuffer[i].lgrpi1_name;
lvi.state = 0;
lvi.iImage = 0;
iItem = ListView_InsertItem(hwndLV, &lvi);
ListView_SetItemText(hwndLV, iItem, 1,
pBuffer[i].lgrpi1_comment);
}
NetApiBufferFree(pBuffer);
/* No more data left */
if (netStatus != ERROR_MORE_DATA)
break;
}
}
static BOOL
AddSelectedGroupsToUser(HWND hwndDlg,
PMEMBERSHIP_USER_DATA pUserData)
{
HWND hwndLV;
INT nItem;
TCHAR szGroupName[UNLEN];
BOOL bResult = FALSE;
BOOL bFound;
DWORD i;
LOCALGROUP_MEMBERS_INFO_3 memberInfo;
NET_API_STATUS status;
hwndLV = GetDlgItem(hwndDlg, IDC_USER_ADD_MEMBERSHIP_LIST);
if (ListView_GetSelectedCount(hwndLV) > 0)
{
nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
while (nItem != -1)
{
/* Get the new user name */
ListView_GetItemText(hwndLV,
nItem, 0,
szGroupName,
UNLEN);
bFound = FALSE;
for (i = 0; i < pUserData->dwGroupCount; i++)
{
if (_tcscmp(pUserData->pGroupData[i].lgrui0_name, szGroupName) == 0)
bFound = TRUE;
}
if (!bFound)
{
memberInfo.lgrmi3_domainandname = pUserData->szUserName;
status = NetLocalGroupAddMembers(NULL, szGroupName, 3,
(LPBYTE)&memberInfo, 1);
if (status == NERR_Success)
{
DebugPrintf(_TEXT("Selected group: %s"), szGroupName);
bResult = TRUE;
}
else
{
TCHAR szText[256];
wsprintf(szText, TEXT("Error: %u"), status);
MessageBox(NULL, szText, TEXT("NetLocalGroupAddMembers"), MB_ICONERROR | MB_OK);
}
}
nItem = ListView_GetNextItem(hwndLV, nItem, LVNI_SELECTED);
}
}
return bResult;
}
INT_PTR CALLBACK
AddGroupToUserDlgProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PMEMBERSHIP_USER_DATA pUserData;
UNREFERENCED_PARAMETER(wParam);
pUserData= (PMEMBERSHIP_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch (uMsg)
{
case WM_INITDIALOG:
pUserData= (PMEMBERSHIP_USER_DATA)lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
InitUserGroupsList(hwndDlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
if (AddSelectedGroupsToUser(hwndDlg, pUserData))
EndDialog(hwndDlg, IDOK);
else
EndDialog(hwndDlg, IDCANCEL);
break;
case IDCANCEL:
EndDialog(hwndDlg, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
static VOID
AddGroupToUser(HWND hwndDlg,
PMEMBERSHIP_USER_DATA pUserData)
{
HWND hwndLV;
NET_API_STATUS status;
DWORD i;
DWORD dwTotal;
LV_ITEM lvi;
if (DialogBoxParam(hApplet,
MAKEINTRESOURCE(IDD_USER_ADD_MEMBERSHIP),
hwndDlg,
AddGroupToUserDlgProc,
(LPARAM)pUserData) == IDOK)
{
// TODO: Update Membership list!
hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST);
if (pUserData->pGroupData)
NetApiBufferFree(pUserData->pGroupData);
(void)ListView_DeleteAllItems(hwndLV);
status = NetUserGetLocalGroups(NULL, pUserData->szUserName, 0, 0,
(LPBYTE*)&pUserData->pGroupData,
MAX_PREFERRED_LENGTH,
&pUserData->dwGroupCount,
&dwTotal);
if (status != NERR_Success)
return;
for (i = 0; i < pUserData->dwGroupCount; i++)
{
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
lvi.pszText = pUserData->pGroupData[i].lgrui0_name;
lvi.state = 0;
lvi.iImage = 0;
(void)ListView_InsertItem(hwndLV, &lvi);
}
}
}
static BOOL
OnUserPropSheetNotify(HWND hwndDlg,
PMEMBERSHIP_USER_DATA pUserData,
LPARAM lParam)
{
LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lParam;
switch (((LPNMHDR)lParam)->idFrom)
{
case IDC_USER_MEMBERSHIP_LIST:
switch (((LPNMHDR)lParam)->code)
{
case NM_CLICK:
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_REMOVE), (lpnmlv->iItem != -1));
break;
case LVN_KEYDOWN:
if (((LPNMLVKEYDOWN)lParam)->wVKey == VK_DELETE)
{
RemoveGroupFromUser(hwndDlg, pUserData);
}
break;
}
break;
}
return FALSE;
}
INT_PTR CALLBACK
UserMembershipPageProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PMEMBERSHIP_USER_DATA pUserData;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(hwndDlg);
pUserData= (PMEMBERSHIP_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch (uMsg)
{
case WM_INITDIALOG:
pUserData = (PMEMBERSHIP_USER_DATA)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(MEMBERSHIP_USER_DATA) +
lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
GetUserMembershipData(hwndDlg, pUserData);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_USER_MEMBERSHIP_ADD:
AddGroupToUser(hwndDlg, pUserData);
break;
case IDC_USER_MEMBERSHIP_REMOVE:
RemoveGroupFromUser(hwndDlg, pUserData);
break;
}
break;
case WM_NOTIFY:
if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
{
return TRUE;
}
else
{
return OnUserPropSheetNotify(hwndDlg, pUserData, lParam);
}
break;
case WM_DESTROY:
if (pUserData->pGroupData)
NetApiBufferFree(pUserData->pGroupData);
HeapFree(GetProcessHeap(), 0, pUserData);
break;
}
return FALSE;
}
static VOID
UpdateUserOptions(HWND hwndDlg,
PGENERAL_USER_DATA pUserData,
BOOL bInit)
{
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE),
!pUserData->dwPasswordExpired);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES),
!pUserData->dwPasswordExpired);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE),
(pUserData->dwFlags & (UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD)) == 0);
EnableWindow(GetDlgItem(hwndDlg, IDC_USER_GENERAL_LOCKED),
(pUserData->dwFlags & UF_LOCKOUT) != 0);
if (bInit)
{
CheckDlgButton(hwndDlg, IDC_USER_GENERAL_FORCE_CHANGE,
pUserData->dwPasswordExpired ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_USER_GENERAL_CANNOT_CHANGE,
(pUserData->dwFlags & UF_PASSWD_CANT_CHANGE) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_USER_GENERAL_NEVER_EXPIRES,
(pUserData->dwFlags & UF_DONT_EXPIRE_PASSWD) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_USER_GENERAL_DISABLED,
(pUserData->dwFlags & UF_ACCOUNTDISABLE) ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_USER_GENERAL_LOCKED,
(pUserData->dwFlags & UF_LOCKOUT) ? BST_CHECKED : BST_UNCHECKED);
}
}
static VOID
GetUserGeneralData(HWND hwndDlg,
PGENERAL_USER_DATA pUserData)
{
PUSER_INFO_3 pUserInfo = NULL;
SetDlgItemText(hwndDlg, IDC_USER_GENERAL_NAME, pUserData->szUserName);
NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
SetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, pUserInfo->usri3_full_name);
SetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, pUserInfo->usri3_comment);
pUserData->dwFlags = pUserInfo->usri3_flags;
pUserData->dwPasswordExpired = pUserInfo->usri3_password_expired;
NetApiBufferFree(pUserInfo);
UpdateUserOptions(hwndDlg, pUserData, TRUE);
}
static BOOL
SetUserGeneralData(HWND hwndDlg,
PGENERAL_USER_DATA pUserData)
{
PUSER_INFO_3 pUserInfo = NULL;
LPTSTR pszFullName = NULL;
LPTSTR pszComment = NULL;
NET_API_STATUS status;
DWORD dwIndex;
INT nLength;
NetUserGetInfo(NULL, pUserData->szUserName, 3, (LPBYTE*)&pUserInfo);
pUserInfo->usri3_flags =
(pUserData->dwFlags & VALID_GENERAL_FLAGS) |
(pUserInfo->usri3_flags & ~VALID_GENERAL_FLAGS);
pUserInfo->usri3_password_expired = pUserData->dwPasswordExpired;
nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_GENERAL_FULL_NAME));
if (nLength == 0)
{
pUserInfo->usri3_full_name = NULL;
}
else
{
pszFullName = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
GetDlgItemText(hwndDlg, IDC_USER_GENERAL_FULL_NAME, pszFullName, nLength + 1);
pUserInfo->usri3_full_name = pszFullName;
}
nLength = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_USER_GENERAL_DESCRIPTION));
if (nLength == 0)
{
pUserInfo->usri3_full_name = NULL;
}
else
{
pszComment = HeapAlloc(GetProcessHeap(), 0, (nLength + 1) * sizeof(TCHAR));
GetDlgItemText(hwndDlg, IDC_USER_GENERAL_DESCRIPTION, pszComment, nLength + 1);
pUserInfo->usri3_comment = pszComment;
}
status = NetUserSetInfo(NULL, pUserData->szUserName, 3, (LPBYTE)pUserInfo, &dwIndex);
if (status != NERR_Success)
{
DebugPrintf(_T("Status: %lu Index: %lu"), status, dwIndex);
}
if (pszFullName)
HeapFree(GetProcessHeap(), 0, pszFullName);
if (pszComment)
HeapFree(GetProcessHeap(), 0, pszComment);
NetApiBufferFree(pUserInfo);
return (status == NERR_Success);
}
INT_PTR CALLBACK
UserGeneralPageProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PGENERAL_USER_DATA pUserData;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(hwndDlg);
pUserData= (PGENERAL_USER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch (uMsg)
{
case WM_INITDIALOG:
pUserData = (PGENERAL_USER_DATA)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(GENERAL_USER_DATA) +
lstrlen((LPTSTR)((PROPSHEETPAGE *)lParam)->lParam) * sizeof(TCHAR));
lstrcpy(pUserData->szUserName, (LPTSTR)((PROPSHEETPAGE *)lParam)->lParam);
SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)pUserData);
GetUserGeneralData(hwndDlg,
pUserData);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_USER_GENERAL_FULL_NAME:
case IDC_USER_GENERAL_DESCRIPTION:
if (HIWORD(wParam) == EN_CHANGE)
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
case IDC_USER_GENERAL_FORCE_CHANGE:
pUserData->dwPasswordExpired = !pUserData->dwPasswordExpired;
UpdateUserOptions(hwndDlg, pUserData, FALSE);
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
case IDC_USER_GENERAL_CANNOT_CHANGE:
pUserData->dwFlags ^= UF_PASSWD_CANT_CHANGE;
UpdateUserOptions(hwndDlg, pUserData, FALSE);
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
case IDC_USER_GENERAL_NEVER_EXPIRES:
pUserData->dwFlags ^= UF_DONT_EXPIRE_PASSWD;
UpdateUserOptions(hwndDlg, pUserData, FALSE);
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
case IDC_USER_GENERAL_DISABLED:
pUserData->dwFlags ^= UF_ACCOUNTDISABLE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
case IDC_USER_GENERAL_LOCKED:
pUserData->dwFlags ^= UF_LOCKOUT;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
break;
case WM_NOTIFY:
if (((LPPSHNOTIFY)lParam)->hdr.code == PSN_APPLY)
{
SetUserGeneralData(hwndDlg, pUserData);
return TRUE;
}
break;
case WM_DESTROY:
HeapFree(GetProcessHeap(), 0, pUserData);
break;
}
return FALSE;
}
static VOID
InitUserPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPTSTR pszUser)
{
ZeroMemory(psp, sizeof(PROPSHEETPAGE));
psp->dwSize = sizeof(PROPSHEETPAGE);
psp->dwFlags = PSP_DEFAULT;
psp->hInstance = hApplet;
psp->pszTemplate = MAKEINTRESOURCE(idDlg);
psp->pfnDlgProc = DlgProc;
psp->lParam = (LPARAM)pszUser;
}
BOOL
UserProperties(HWND hwndDlg)
{
PROPSHEETPAGE psp[3];
PROPSHEETHEADER psh;
TCHAR szUserName[UNLEN];
INT nItem;
HWND hwndLV;
hwndLV = GetDlgItem(hwndDlg, IDC_USERS_LIST);
nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
if (nItem == -1)
return FALSE;
/* Get the new user name */
ListView_GetItemText(hwndLV,
nItem, 0,
szUserName,
UNLEN);
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
psh.hwndParent = hwndDlg;
psh.hInstance = hApplet;
psh.hIcon = NULL;
psh.pszCaption = szUserName;
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
psh.ppsp = psp;
InitUserPropSheetPage(&psp[0], IDD_USER_GENERAL, UserGeneralPageProc, szUserName);
InitUserPropSheetPage(&psp[1], IDD_USER_MEMBERSHIP, UserMembershipPageProc, szUserName);
InitUserPropSheetPage(&psp[2], IDD_USER_PROFILE, UserProfilePageProc, szUserName);
return (PropertySheet(&psh) == IDOK);
}