Michael Müller : aclui: Populate the users list.

Alexandre Julliard julliard at winehq.org
Thu Mar 4 15:53:37 CST 2021


Module: wine
Branch: master
Commit: f57356ad44548ec0387beec9b68f11f7a37721ed
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f57356ad44548ec0387beec9b68f11f7a37721ed

Author: Michael Müller <michael at fds-team.de>
Date:   Sun Feb 28 10:27:46 2021 -0600

aclui: Populate the users list.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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;
     }




More information about the wine-cvs mailing list