[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    [PATCH v2 2/5] aclui: Populate the users list.
From:       Zebediah Figura <z.figura12 () gmail ! com>
Date:       2021-02-28 16:27:46
Message-ID: 20210228162749.901629-2-z.figura12 () gmail ! com
[Download RAW message or body]

From: Michael Müller <michael@fds-team.de>

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
 dlls/aclui/Makefile.in  |   2 +-
 dlls/aclui/aclui_main.c | 159 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 160 insertions(+), 1 deletion(-)

diff --git a/dlls/aclui/Makefile.in b/dlls/aclui/Makefile.in
index da3aa00084e..f93e5da6c8d 100644
--- a/dlls/aclui/Makefile.in
+++ b/dlls/aclui/Makefile.in
@@ -1,6 +1,6 @@
 MODULE    = aclui.dll
 IMPORTLIB = aclui
-IMPORTS   = comctl32 user32
+IMPORTS   = comctl32 user32 advapi32
 
 EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native
 
diff --git a/dlls/aclui/aclui_main.c b/dlls/aclui/aclui_main.c
index 3989c3017aa..199e7295adc 100644
--- a/dlls/aclui/aclui_main.c
+++ b/dlls/aclui/aclui_main.c
@@ -39,23 +39,178 @@ WINE_DEFAULT_DEBUG_CHANNEL(aclui);
 #define ISecurityInformation_GetSecurity(This, info, sd, def) \
(This)->lpVtbl->GetSecurity(This, info, sd, def)  #define \
ISecurityInformation_GetAccessRights(This, type, flags, access, count, def) \
(This)->lpVtbl->GetAccessRights(This, type, flags, access, count, def)  
+struct user
+{
+    WCHAR *name;
+    PSID sid;
+};
+
 struct security_page
 {
+    ISecurityInformation *security;
     SI_OBJECT_INFO info;
+    PSECURITY_DESCRIPTOR sd;
+
+    struct user *users;
+    unsigned int user_count;
 
     HWND dialog;
 };
 
 static HINSTANCE aclui_instance;
 
+static WCHAR *get_sid_name(PSID sid, SID_NAME_USE *sid_type)
+{
+    WCHAR *name, *domain;
+    DWORD domain_len = 0;
+    DWORD name_len = 0;
+    BOOL ret;
+
+    LookupAccountSidW(NULL, sid, NULL, &name_len, NULL, &domain_len, sid_type);
+    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+        return NULL;
+    if (!(name = malloc(name_len * sizeof(WCHAR))))
+        return NULL;
+    if (!(domain = malloc(domain_len * sizeof(WCHAR))))
+    {
+        free(name);
+        return NULL;
+    }
+
+    ret = LookupAccountSidW(NULL, sid, name, &name_len, domain, &domain_len, \
sid_type); +    free(domain);
+    if (ret) return name;
+    free(name);
+    return NULL;
+}
+
+static void add_user(struct security_page *page, PSID sid)
+{
+    struct user *new_array, *user;
+    SID_NAME_USE sid_type;
+    unsigned int i;
+    LVITEMW item;
+    WCHAR *name;
+
+    /* check if we already processed this user or group */
+    for (i = 0; i < page->user_count; ++i)
+    {
+        if (EqualSid(sid, page->users[i].sid))
+            return;
+    }
+
+    if (!(name = get_sid_name(sid, &sid_type)))
+        return;
+
+    if (!(new_array = realloc(page->users, (page->user_count + 1) * \
sizeof(*page->users)))) +        return;
+    page->users = new_array;
+    user = &page->users[page->user_count++];
+
+    user->name = name;
+    user->sid = sid;
+
+    item.mask     = LVIF_PARAM | LVIF_TEXT;
+    item.iItem    = -1;
+    item.iSubItem = 0;
+    item.pszText  = name;
+    item.lParam   = (LPARAM)user;
+
+    SendMessageW(GetDlgItem(page->dialog, IDC_USERS), LVM_INSERTITEMW, 0, \
(LPARAM)&item); +}
+
+static PSID get_sid_from_ace(ACE_HEADER *ace)
+{
+    switch (ace->AceType)
+    {
+        case ACCESS_ALLOWED_ACE_TYPE:
+            return &((ACCESS_ALLOWED_ACE *)ace)->SidStart;
+        case ACCESS_DENIED_ACE_TYPE:
+            return &((ACCESS_DENIED_ACE *)ace)->SidStart;
+        default:
+            FIXME("Unhandled ACE type %#x.\n", ace->AceType);
+            return NULL;
+    }
+}
+
+static void init_users(struct security_page *page)
+{
+    BOOL defaulted, present;
+    ACE_HEADER *ace;
+    DWORD index;
+    ACL *dacl;
+    PSID sid;
+
+    if (!GetSecurityDescriptorDacl(page->sd, &present, &dacl, &defaulted))
+    {
+        ERR("Failed to query descriptor information, error %u.\n", GetLastError());
+        return;
+    }
+
+    if (!present)
+        return;
+
+    for (index = 0; index < dacl->AceCount; index++)
+    {
+        if (!GetAce(dacl, index, (void **)&ace))
+            break;
+        if (!(sid = get_sid_from_ace(ace)))
+            continue;
+        add_user(page, sid);
+    }
+}
+
 static void security_page_free(struct security_page *page)
 {
+    unsigned int i;
+
+    for (i = 0; i < page->user_count; ++i)
+        free(page->users[i].name);
+    free(page->users);
+
+    LocalFree(page->sd);
+    if (page->security)
+        ISecurityInformation_Release(page->security);
     free(page);
 }
 
 static void security_page_init_dlg(HWND hwnd, struct security_page *page)
 {
+    LVCOLUMNW column;
+    HWND control;
+    HRESULT hr;
+    RECT rect;
+
     page->dialog = hwnd;
+
+    if (FAILED(hr = ISecurityInformation_GetSecurity(page->security,
+            DACL_SECURITY_INFORMATION, &page->sd, FALSE)))
+    {
+        ERR("Failed to get security descriptor, hr %#x.\n", hr);
+        return;
+    }
+
+    control = GetDlgItem(hwnd, IDC_USERS);
+    SendMessageW(control, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, \
LVS_EX_FULLROWSELECT); +
+    GetClientRect(control, &rect);
+    column.mask = LVCF_FMT | LVCF_WIDTH;
+    column.fmt = LVCFMT_LEFT;
+    column.cx = rect.right - rect.left;
+    SendMessageW(control, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
+
+    init_users(page);
+
+    if (page->user_count)
+    {
+        LVITEMW item;
+        item.mask = LVIF_STATE;
+        item.iItem = 0;
+        item.iSubItem = 0;
+        item.state = LVIS_FOCUSED | LVIS_SELECTED;
+        item.stateMask = item.state;
+        SendMessageW(control, LVM_SETITEMW, 0, (LPARAM)&item);
+    }
 }
 
 static INT_PTR CALLBACK security_page_proc(HWND dialog, UINT msg, WPARAM wparam, \
LPARAM lparam) @@ -101,6 +256,9 @@ HPROPSHEETPAGE WINAPI \
CreateSecurityPage(ISecurityInformation *security)  return NULL;
     }
 
+    page->security = security;
+    ISecurityInformation_AddRef(security);
+
     memset(&propsheet, 0, sizeof(propsheet));
     propsheet.dwSize        = sizeof(propsheet);
     propsheet.dwFlags       = PSP_DEFAULT | PSP_USECALLBACK;
@@ -119,6 +277,7 @@ HPROPSHEETPAGE WINAPI CreateSecurityPage(ISecurityInformation \
*security)  if (!(ret = CreatePropertySheetPageW(&propsheet)))
     {
         ERR("Failed to create property sheet page.\n");
+        ISecurityInformation_Release(security);
         free(page);
         return NULL;
     }
-- 
2.30.1


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic