mirror of
https://github.com/reactos/reactos.git
synced 2024-10-31 03:48:17 +00:00
937 lines
29 KiB
C
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);
|
|
}
|