[PATCH 4/5] aclui: Populate the access list.
Zebediah Figura
z.figura12 at gmail.com
Sat Feb 27 16:53:14 CST 2021
From: Michael Müller <michael at fds-team.de>
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/aclui/aclui.rc | 5 ++
dlls/aclui/aclui_main.c | 164 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 169 insertions(+)
diff --git a/dlls/aclui/aclui.rc b/dlls/aclui/aclui.rc
index 6e6b3c268b5..8be0eb0b71f 100644
--- a/dlls/aclui/aclui.rc
+++ b/dlls/aclui/aclui.rc
@@ -37,6 +37,11 @@ BEGIN
CONTROL "", IDC_ACE, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | LVS_SINGLESEL | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 5, 115, 230, 95, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
END
+STRINGTABLE
+BEGIN
+ IDS_PERMISSION_FOR "Permissions for %1"
+END
+
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/* @makedep: user_icons.bmp */
diff --git a/dlls/aclui/aclui_main.c b/dlls/aclui/aclui_main.c
index 9c581610bfe..982811948d3 100644
--- a/dlls/aclui/aclui_main.c
+++ b/dlls/aclui/aclui_main.c
@@ -51,6 +51,9 @@ struct security_page
SI_OBJECT_INFO info;
PSECURITY_DESCRIPTOR sd;
+ SI_ACCESS *access;
+ ULONG access_count;
+
struct user *users;
unsigned int user_count;
@@ -60,6 +63,19 @@ struct security_page
static HINSTANCE aclui_instance;
+static WCHAR *WINAPIV load_formatstr(UINT resource, ...)
+{
+ __ms_va_list valist;
+ WCHAR *str;
+ DWORD ret;
+
+ __ms_va_start(valist, resource);
+ ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE,
+ aclui_instance, resource, 0, (WCHAR*)&str, 0, &valist);
+ __ms_va_end(valist);
+ return ret ? str : NULL;
+}
+
static WCHAR *get_sid_name(PSID sid, SID_NAME_USE *sid_type)
{
WCHAR *name, *domain;
@@ -135,6 +151,80 @@ static PSID get_sid_from_ace(ACE_HEADER *ace)
}
}
+static void compute_access_masks(PSECURITY_DESCRIPTOR sd, PSID sid, ACCESS_MASK *allowed, ACCESS_MASK *denied)
+{
+ BOOL defaulted, present;
+ ACE_HEADER *ace;
+ PSID ace_sid;
+ DWORD index;
+ ACL *dacl;
+
+ *allowed = 0;
+ *denied = 0;
+
+ if (!GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted) || !present)
+ return;
+
+ for (index = 0; index < dacl->AceCount; index++)
+ {
+ if (!GetAce(dacl, index, (void**)&ace))
+ break;
+
+ ace_sid = get_sid_from_ace(ace);
+ if (!ace_sid || !EqualSid(ace_sid, sid))
+ continue;
+
+ if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
+ *allowed |= ((ACCESS_ALLOWED_ACE*)ace)->Mask;
+ else if (ace->AceType == ACCESS_DENIED_ACE_TYPE)
+ *denied |= ((ACCESS_DENIED_ACE*)ace)->Mask;
+ }
+}
+
+static void update_access_list(struct security_page *page, struct user *user)
+{
+ ACCESS_MASK allowed, denied;
+ WCHAR *infotext;
+ ULONG i, index;
+ LVITEMW item;
+ HWND control;
+
+ compute_access_masks(page->sd, user->sid, &allowed, &denied);
+
+ if ((infotext = load_formatstr(IDS_PERMISSION_FOR, user->name)))
+ {
+ SetDlgItemTextW(page->dialog, IDC_ACE_USER, infotext);
+ LocalFree(infotext);
+ }
+
+ control = GetDlgItem(page->dialog, IDC_ACE);
+ index = 0;
+ for (i = 0; i < page->access_count; i++)
+ {
+ if (!(page->access[i].dwFlags & SI_ACCESS_GENERAL))
+ continue;
+
+ item.mask = LVIF_TEXT;
+ item.iItem = index;
+
+ item.iSubItem = 1;
+ if ((page->access[i].mask & allowed) == page->access[i].mask)
+ item.pszText = (WCHAR *)L"X";
+ else
+ item.pszText = (WCHAR *)L"-";
+ SendMessageW(control, LVM_SETITEMW, 0, (LPARAM)&item);
+
+ item.iSubItem = 2;
+ if ((page->access[i].mask & denied) == page->access[i].mask)
+ item.pszText = (WCHAR *)L"X";
+ else
+ item.pszText = (WCHAR *)L"-";
+ SendMessageW(control, LVM_SETITEMW, 0, (LPARAM)&item);
+
+ index++;
+ }
+}
+
static void init_users(struct security_page *page)
{
BOOL defaulted, present;
@@ -162,6 +252,37 @@ static void init_users(struct security_page *page)
}
}
+static void init_access_list(struct security_page *page)
+{
+ ULONG i, index;
+ WCHAR str[256];
+ LVITEMW item;
+ HWND control;
+
+ control = GetDlgItem(page->dialog, IDC_ACE);
+ index = 0;
+ for (i = 0; i < page->access_count; i++)
+ {
+ if (!(page->access[i].dwFlags & SI_ACCESS_GENERAL))
+ continue;
+
+ item.mask = LVIF_TEXT;
+ item.iItem = index;
+ item.iSubItem = 0;
+ if (IS_INTRESOURCE(page->access[i].pszName))
+ {
+ str[0] = 0;
+ LoadStringW(page->info.hInstance, (DWORD_PTR)page->access[i].pszName, str, ARRAY_SIZE(str));
+ item.pszText = str;
+ }
+ else
+ item.pszText = (WCHAR *)page->access[i].pszName;
+ SendMessageW(control, LVM_INSERTITEMW, 0, (LPARAM)&item);
+
+ index++;
+ }
+}
+
static HIMAGELIST create_image_list(UINT resource, UINT width, UINT height, UINT count, COLORREF mask_color)
{
HIMAGELIST image_list;
@@ -207,6 +328,7 @@ static void security_page_init_dlg(HWND hwnd, struct security_page *page)
LVCOLUMNW column;
HWND control;
HRESULT hr;
+ ULONG def;
RECT rect;
page->dialog = hwnd;
@@ -218,6 +340,15 @@ static void security_page_init_dlg(HWND hwnd, struct security_page *page)
return;
}
+ if (FAILED(hr = ISecurityInformation_GetAccessRights(page->security,
+ NULL, 0, &page->access, &page->access_count, &def)))
+ {
+ ERR("Failed to get access mapping, hr %#x.\n", hr);
+ return;
+ }
+
+ /* user list */
+
control = GetDlgItem(hwnd, IDC_USERS);
SendMessageW(control, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
@@ -233,6 +364,23 @@ static void security_page_init_dlg(HWND hwnd, struct security_page *page)
init_users(page);
+ /* ACE list */
+
+ control = GetDlgItem(hwnd, IDC_ACE);
+ SendMessageW(control, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
+
+ column.mask = LVCF_FMT | LVCF_WIDTH;
+ column.fmt = LVCFMT_LEFT;
+ column.cx = 170;
+ SendMessageW(control, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
+
+ column.fmt = LVCFMT_CENTER;
+ column.cx = 85;
+ SendMessageW(control, LVM_INSERTCOLUMNW, 1, (LPARAM)&column);
+ SendMessageW(control, LVM_INSERTCOLUMNW, 2, (LPARAM)&column);
+
+ init_access_list(page);
+
if (page->user_count)
{
LVITEMW item;
@@ -252,9 +400,25 @@ static INT_PTR CALLBACK security_page_proc(HWND dialog, UINT msg, WPARAM wparam,
case WM_INITDIALOG:
{
PROPSHEETPAGEW *propsheet = (PROPSHEETPAGEW *)lparam;
+ SetWindowLongPtrW(dialog, DWLP_USER, propsheet->lParam);
security_page_init_dlg(dialog, (struct security_page *)propsheet->lParam);
break;
}
+
+ case WM_NOTIFY:
+ {
+ struct security_page *page = (struct security_page *)GetWindowLongPtrW(dialog, DWLP_USER);
+ NMHDR *hdr = (NMHDR *)lparam;
+
+ if (hdr->hwndFrom == GetDlgItem(dialog, IDC_USERS) && hdr->code == LVN_ITEMCHANGED)
+ {
+ NMLISTVIEW *listview = (NMLISTVIEW *)lparam;
+ if (!(listview->uOldState & LVIS_SELECTED) && (listview->uNewState & LVIS_SELECTED))
+ update_access_list(page, (struct user *)listview->lParam);
+ return TRUE;
+ }
+ break;
+ }
}
return FALSE;
}
--
2.30.1
More information about the wine-devel
mailing list