mirror of
https://github.com/reactos/reactos.git
synced 2024-11-01 12:26:32 +00:00
8532f1874a
- Add GetDlgItemTextAlloc and GetComboBoxLBTextAlloc helper functions. - Get the text data correctly even if the text length is zero. CORE-18275
489 lines
13 KiB
C
489 lines
13 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS User Manager Control Panel
|
|
* FILE: dll/cpl/usrmgr/groups.c
|
|
* PURPOSE: Groups property page
|
|
*
|
|
* PROGRAMMERS: Eric Kohl
|
|
*/
|
|
|
|
#include "usrmgr.h"
|
|
|
|
typedef struct _GROUP_DATA
|
|
{
|
|
HMENU hPopupMenu;
|
|
|
|
INT iCurrentItem;
|
|
|
|
} GROUP_DATA, *PGROUP_DATA;
|
|
|
|
|
|
static VOID
|
|
SetGroupsListColumns(HWND hwndListView)
|
|
{
|
|
LV_COLUMN column;
|
|
RECT rect;
|
|
TCHAR szStr[32];
|
|
|
|
GetClientRect(hwndListView, &rect);
|
|
|
|
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(hwndListView, 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(hwndListView, 1, &column);
|
|
}
|
|
|
|
|
|
static VOID
|
|
UpdateGroupsList(HWND hwndListView)
|
|
{
|
|
NET_API_STATUS netStatus;
|
|
PLOCALGROUP_INFO_1 pBuffer;
|
|
DWORD entriesread;
|
|
DWORD totalentries;
|
|
DWORD_PTR resume_handle = 0;
|
|
DWORD i;
|
|
LV_ITEM lvi;
|
|
INT iItem;
|
|
|
|
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(hwndListView, &lvi);
|
|
|
|
ListView_SetItemText(hwndListView, iItem, 1,
|
|
pBuffer[i].lgrpi1_comment);
|
|
}
|
|
|
|
NetApiBufferFree(pBuffer);
|
|
|
|
/* No more data left */
|
|
if (netStatus != ERROR_MORE_DATA)
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static VOID
|
|
UpdateGroupProperties(HWND hwndDlg)
|
|
{
|
|
TCHAR szGroupName[UNLEN + 1];
|
|
INT iItem;
|
|
HWND hwndLV;
|
|
PLOCALGROUP_INFO_1 pGroupInfo = NULL;
|
|
|
|
hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
|
|
iItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
|
|
if (iItem == -1)
|
|
return;
|
|
|
|
/* Get the group name */
|
|
ListView_GetItemText(hwndLV,
|
|
iItem, 0,
|
|
szGroupName,
|
|
UNLEN + 1);
|
|
|
|
NetLocalGroupGetInfo(NULL, szGroupName, 1, (LPBYTE*)&pGroupInfo);
|
|
|
|
ListView_SetItemText(hwndLV, iItem, 1,
|
|
pGroupInfo->lgrpi1_comment);
|
|
|
|
NetApiBufferFree(pGroupInfo);
|
|
}
|
|
|
|
|
|
INT_PTR CALLBACK
|
|
NewGroupDlgProc(HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
PLOCALGROUP_INFO_1 groupInfo;
|
|
INT nLength;
|
|
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
|
|
groupInfo = (PLOCALGROUP_INFO_1)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
|
|
groupInfo = (PLOCALGROUP_INFO_1)lParam;
|
|
SendDlgItemMessage(hwndDlg, IDC_GROUP_NEW_NAME, EM_SETLIMITTEXT, 20, 0);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_GROUP_NEW_NAME:
|
|
if (HIWORD(wParam) == EN_CHANGE)
|
|
{
|
|
nLength = SendDlgItemMessage(hwndDlg, IDC_GROUP_NEW_NAME, WM_GETTEXTLENGTH, 0, 0);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDOK), (nLength > 0));
|
|
}
|
|
break;
|
|
|
|
case IDOK:
|
|
if (!CheckAccountName(hwndDlg, IDC_GROUP_NEW_NAME, NULL))
|
|
{
|
|
SetFocus(GetDlgItem(hwndDlg, IDC_GROUP_NEW_NAME));
|
|
SendDlgItemMessage(hwndDlg, IDC_GROUP_NEW_NAME, EM_SETSEL, 0, -1);
|
|
break;
|
|
}
|
|
|
|
/* Get Name */
|
|
groupInfo->lgrpi1_name = GetDlgItemTextAlloc(hwndDlg, IDC_GROUP_NEW_NAME);
|
|
|
|
/* Get Description */
|
|
groupInfo->lgrpi1_comment = GetDlgItemTextAlloc(hwndDlg, IDC_GROUP_NEW_DESCRIPTION);
|
|
|
|
EndDialog(hwndDlg, IDOK);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hwndDlg, IDCANCEL);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static VOID
|
|
GroupNew(HWND hwndDlg)
|
|
{
|
|
NET_API_STATUS status;
|
|
LOCALGROUP_INFO_1 group;
|
|
LV_ITEM lvi;
|
|
INT iItem;
|
|
HWND hwndLV;
|
|
|
|
ZeroMemory(&group, sizeof(LOCALGROUP_INFO_1));
|
|
|
|
if (DialogBoxParam(hApplet,
|
|
MAKEINTRESOURCE(IDD_GROUP_NEW),
|
|
hwndDlg,
|
|
NewGroupDlgProc,
|
|
(LPARAM)&group) == IDOK)
|
|
{
|
|
status = NetLocalGroupAdd(NULL,
|
|
1,
|
|
(LPBYTE)&group,
|
|
NULL);
|
|
if (status != NERR_Success)
|
|
{
|
|
TCHAR szText[256];
|
|
wsprintf(szText, TEXT("Error: %u"), status);
|
|
MessageBox(NULL, szText, TEXT("NetUserAdd"), MB_ICONERROR | MB_OK);
|
|
return;
|
|
}
|
|
|
|
hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
|
|
|
|
ZeroMemory(&lvi, sizeof(lvi));
|
|
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
|
|
lvi.pszText = group.lgrpi1_name;
|
|
lvi.state = 0;
|
|
lvi.iImage = 0;
|
|
iItem = ListView_InsertItem(hwndLV, &lvi);
|
|
|
|
ListView_SetItemText(hwndLV, iItem, 1,
|
|
group.lgrpi1_comment);
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(), 0, group.lgrpi1_name);
|
|
HeapFree(GetProcessHeap(), 0, group.lgrpi1_comment);
|
|
}
|
|
|
|
|
|
static VOID
|
|
GroupRename(HWND hwndDlg)
|
|
{
|
|
INT nItem;
|
|
HWND hwndLV;
|
|
|
|
hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
|
|
nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
|
|
if (nItem != -1)
|
|
{
|
|
(void)ListView_EditLabel(hwndLV, nItem);
|
|
}
|
|
}
|
|
|
|
|
|
static BOOL
|
|
GroupDelete(HWND hwndDlg)
|
|
{
|
|
TCHAR szGroupName[UNLEN + 1];
|
|
TCHAR szText[256];
|
|
INT nItem;
|
|
HWND hwndLV;
|
|
NET_API_STATUS status;
|
|
|
|
hwndLV = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
|
|
nItem = ListView_GetNextItem(hwndLV, -1, LVNI_SELECTED);
|
|
if (nItem == -1)
|
|
return FALSE;
|
|
|
|
/* Get the new group name */
|
|
ListView_GetItemText(hwndLV,
|
|
nItem, 0,
|
|
szGroupName,
|
|
UNLEN + 1);
|
|
|
|
/* Display a warning message, because the delete operation cannot be reverted */
|
|
wsprintf(szText, TEXT("Dou you really want to delete the user group \"%s\"?"), szGroupName);
|
|
if (MessageBox(NULL, szText, TEXT("User Groups"), MB_ICONWARNING | MB_YESNO) == IDNO)
|
|
return FALSE;
|
|
|
|
/* Delete the group */
|
|
status = NetLocalGroupDel(NULL, szGroupName);
|
|
if (status != NERR_Success)
|
|
{
|
|
TCHAR szText[256];
|
|
wsprintf(szText, TEXT("Error: %u"), status);
|
|
MessageBox(NULL, szText, TEXT("NetLocalGroupDel"), MB_ICONERROR | MB_OK);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Delete the group from the list */
|
|
(void)ListView_DeleteItem(hwndLV, nItem);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static VOID
|
|
OnGroupsPageInitDialog(HWND hwndDlg)
|
|
{
|
|
HWND hwndListView;
|
|
HIMAGELIST hImgList;
|
|
HICON hIcon;
|
|
|
|
/* 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);
|
|
|
|
hwndListView = GetDlgItem(hwndDlg, IDC_GROUPS_LIST);
|
|
|
|
(VOID)ListView_SetImageList(hwndListView, hImgList, LVSIL_SMALL);
|
|
|
|
(void)ListView_SetExtendedListViewStyle(hwndListView, LVS_EX_FULLROWSELECT);
|
|
|
|
SetGroupsListColumns(hwndListView);
|
|
|
|
UpdateGroupsList(hwndListView);
|
|
}
|
|
|
|
|
|
static BOOL
|
|
OnGroupsPageBeginLabelEdit(LPNMLVDISPINFO pnmv)
|
|
{
|
|
HWND hwndEdit;
|
|
|
|
hwndEdit = ListView_GetEditControl(pnmv->hdr.hwndFrom);
|
|
if (hwndEdit == NULL)
|
|
return TRUE;
|
|
|
|
SendMessage(hwndEdit, EM_SETLIMITTEXT, 20, 0);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static BOOL
|
|
OnGroupsPageEndLabelEdit(LPNMLVDISPINFO pnmv)
|
|
{
|
|
TCHAR szOldGroupName[UNLEN + 1];
|
|
TCHAR szNewGroupName[UNLEN + 1];
|
|
LOCALGROUP_INFO_0 lgrpi0;
|
|
NET_API_STATUS status;
|
|
|
|
/* Leave, if there is no valid listview item */
|
|
if (pnmv->item.iItem == -1)
|
|
return FALSE;
|
|
|
|
/* Get the new user name */
|
|
ListView_GetItemText(pnmv->hdr.hwndFrom,
|
|
pnmv->item.iItem, 0,
|
|
szOldGroupName,
|
|
UNLEN + 1);
|
|
|
|
/* Leave, if the user canceled the edit action */
|
|
if (pnmv->item.pszText == NULL)
|
|
return FALSE;
|
|
|
|
/* Get the new user name */
|
|
lstrcpy(szNewGroupName, pnmv->item.pszText);
|
|
|
|
/* Leave, if the user name was not changed */
|
|
if (lstrcmp(szOldGroupName, szNewGroupName) == 0)
|
|
return FALSE;
|
|
|
|
/* Check the group name for illegal characters */
|
|
if (!CheckAccountName(NULL, 0, szNewGroupName))
|
|
return FALSE;
|
|
|
|
/* Change the user name */
|
|
lgrpi0.lgrpi0_name = szNewGroupName;
|
|
|
|
status = NetLocalGroupSetInfo(NULL, szOldGroupName, 0, (LPBYTE)&lgrpi0, NULL);
|
|
if (status != NERR_Success)
|
|
{
|
|
TCHAR szText[256];
|
|
wsprintf(szText, TEXT("Error: %u"), status);
|
|
MessageBox(NULL, szText, TEXT("NetLocalGroupSetInfo"), MB_ICONERROR | MB_OK);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Update the listview item */
|
|
ListView_SetItemText(pnmv->hdr.hwndFrom,
|
|
pnmv->item.iItem, 0,
|
|
szNewGroupName);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static BOOL
|
|
OnGroupsPageNotify(HWND hwndDlg, PGROUP_DATA pGroupData, NMHDR *phdr)
|
|
{
|
|
LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
|
|
|
|
switch (phdr->idFrom)
|
|
{
|
|
case IDC_GROUPS_LIST:
|
|
switch(phdr->code)
|
|
{
|
|
case NM_CLICK:
|
|
pGroupData->iCurrentItem = lpnmlv->iItem;
|
|
break;
|
|
|
|
case NM_DBLCLK:
|
|
if (lpnmlv->iItem != -1)
|
|
{
|
|
UINT uItem;
|
|
|
|
uItem = GetMenuDefaultItem(GetSubMenu(pGroupData->hPopupMenu, 1),
|
|
FALSE, 0);
|
|
if (uItem != (UINT)-1)
|
|
SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(uItem, 0), 0);
|
|
}
|
|
break;
|
|
|
|
case NM_RCLICK:
|
|
ClientToScreen(GetDlgItem(hwndDlg, IDC_GROUPS_LIST), &lpnmlv->ptAction);
|
|
TrackPopupMenu(GetSubMenu(pGroupData->hPopupMenu, (lpnmlv->iItem == -1) ? 0 : 1),
|
|
TPM_LEFTALIGN, lpnmlv->ptAction.x, lpnmlv->ptAction.y, 0, hwndDlg, NULL);
|
|
break;
|
|
|
|
case LVN_BEGINLABELEDIT:
|
|
return OnGroupsPageBeginLabelEdit((LPNMLVDISPINFO)phdr);
|
|
|
|
case LVN_ENDLABELEDIT:
|
|
return OnGroupsPageEndLabelEdit((LPNMLVDISPINFO)phdr);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
INT_PTR CALLBACK
|
|
GroupsPageProc(HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
PGROUP_DATA pGroupData;
|
|
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
UNREFERENCED_PARAMETER(hwndDlg);
|
|
|
|
|
|
pGroupData = (PGROUP_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pGroupData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GROUP_DATA));
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGroupData);
|
|
|
|
pGroupData->hPopupMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDM_POPUP_GROUP));
|
|
|
|
OnGroupsPageInitDialog(hwndDlg);
|
|
SetMenuDefaultItem(GetSubMenu(pGroupData->hPopupMenu, 1),
|
|
IDM_GROUP_PROPERTIES,
|
|
FALSE);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDM_GROUP_NEW:
|
|
case IDC_GROUPS_ADD:
|
|
GroupNew(hwndDlg);
|
|
break;
|
|
|
|
case IDM_GROUP_RENAME:
|
|
GroupRename(hwndDlg);
|
|
break;
|
|
|
|
case IDM_GROUP_DELETE:
|
|
case IDC_GROUPS_REMOVE:
|
|
GroupDelete(hwndDlg);
|
|
break;
|
|
|
|
case IDM_GROUP_PROPERTIES:
|
|
case IDC_GROUPS_PROPERTIES:
|
|
if (GroupProperties(hwndDlg) == IDOK)
|
|
UpdateGroupProperties(hwndDlg);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
return OnGroupsPageNotify(hwndDlg, pGroupData, (NMHDR *)lParam);
|
|
|
|
case WM_DESTROY:
|
|
DestroyMenu(pGroupData->hPopupMenu);
|
|
HeapFree(GetProcessHeap(), 0, pGroupData);
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|