From: Michael Müller michael@fds-team.de
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/aclui/Makefile.in | 3 ++ dlls/aclui/aclui.rc | 38 ++++++++++++++ dlls/aclui/aclui_main.c | 106 ++++++++++++++++++++++++++++++++++++++-- dlls/aclui/resource.h | 36 ++++++++++++++ 4 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 dlls/aclui/aclui.rc create mode 100644 dlls/aclui/resource.h
diff --git a/dlls/aclui/Makefile.in b/dlls/aclui/Makefile.in index e79b3fe9e33..da3aa00084e 100644 --- a/dlls/aclui/Makefile.in +++ b/dlls/aclui/Makefile.in @@ -1,6 +1,9 @@ MODULE = aclui.dll IMPORTLIB = aclui +IMPORTS = comctl32 user32
EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native
C_SRCS = aclui_main.c + +RC_SRCS = aclui.rc diff --git a/dlls/aclui/aclui.rc b/dlls/aclui/aclui.rc new file mode 100644 index 00000000000..3a03b0550e9 --- /dev/null +++ b/dlls/aclui/aclui.rc @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Michael Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "resource.h" +#include "winresrc.h" + +#pragma makedep po + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +IDD_SECURITY_PROPERTIES DIALOGEX 0, 0, 240, 215 +STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION +CAPTION "Security" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Group or user names:", -1, 5, 5, 230, 10 + CONTROL "", IDC_USERS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | LVS_SORTASCENDING | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 5, 17, 230, 63, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE + + LTEXT "", IDC_ACE_USER, 5, 105, 110, 10 + LTEXT "Allow", -1, 120, 105, 55, 10, SS_CENTER + LTEXT "Deny", -1, 180, 105, 55, 10, SS_CENTER + 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 diff --git a/dlls/aclui/aclui_main.c b/dlls/aclui/aclui_main.c index 1a03f30df24..3989c3017aa 100644 --- a/dlls/aclui/aclui_main.c +++ b/dlls/aclui/aclui_main.c @@ -19,22 +19,110 @@ */
#include <stdarg.h> - +#define COBJMACROS #include "initguid.h" #include "windef.h" #include "winbase.h" #include "winuser.h" #include "winnt.h" #include "aclui.h" +#include "resource.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(aclui);
-HPROPSHEETPAGE WINAPI CreateSecurityPage(LPSECURITYINFO psi) +/* the aclui.h files does not contain the necessary COBJMACROS */ +#define ISecurityInformation_AddRef(This) (This)->lpVtbl->AddRef(This) +#define ISecurityInformation_Release(This) (This)->lpVtbl->Release(This) +#define ISecurityInformation_GetObjectInformation(This, obj) (This)->lpVtbl->GetObjectInformation(This, obj) +#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 security_page +{ + SI_OBJECT_INFO info; + + HWND dialog; +}; + +static HINSTANCE aclui_instance; + +static void security_page_free(struct security_page *page) +{ + free(page); +} + +static void security_page_init_dlg(HWND hwnd, struct security_page *page) +{ + page->dialog = hwnd; +} + +static INT_PTR CALLBACK security_page_proc(HWND dialog, UINT msg, WPARAM wparam, LPARAM lparam) { - FIXME("(%p): stub\n", psi); - return NULL; + switch (msg) + { + case WM_INITDIALOG: + { + PROPSHEETPAGEW *propsheet = (PROPSHEETPAGEW *)lparam; + security_page_init_dlg(dialog, (struct security_page *)propsheet->lParam); + break; + } + } + return FALSE; +} + +static UINT CALLBACK security_page_callback(HWND hwnd, UINT msg, PROPSHEETPAGEW *ppsp) +{ + struct security_page *page = (struct security_page *)ppsp->lParam; + + if (msg == PSPCB_RELEASE) + security_page_free(page); + + return 1; +} + +HPROPSHEETPAGE WINAPI CreateSecurityPage(ISecurityInformation *security) +{ + struct security_page *page; + PROPSHEETPAGEW propsheet; + HPROPSHEETPAGE ret; + + TRACE("%p\n", security); + + InitCommonControls(); + + if (!(page = calloc(1, sizeof(*page)))) + return NULL; + + if (FAILED(ISecurityInformation_GetObjectInformation(security, &page->info))) + { + free(page); + return NULL; + } + + memset(&propsheet, 0, sizeof(propsheet)); + propsheet.dwSize = sizeof(propsheet); + propsheet.dwFlags = PSP_DEFAULT | PSP_USECALLBACK; + propsheet.hInstance = aclui_instance; + propsheet.pszTemplate = (WCHAR *)MAKEINTRESOURCE(IDD_SECURITY_PROPERTIES); + propsheet.pfnDlgProc = security_page_proc; + propsheet.pfnCallback = security_page_callback; + propsheet.lParam = (LPARAM)page; + + if (page->info.dwFlags & SI_PAGE_TITLE) + { + propsheet.pszTitle = page->info.pszPageTitle; + propsheet.dwFlags |= PSP_USETITLE; + } + + if (!(ret = CreatePropertySheetPageW(&propsheet))) + { + ERR("Failed to create property sheet page.\n"); + free(page); + return NULL; + } + return ret; }
BOOL WINAPI EditSecurity(HWND owner, LPSECURITYINFO psi) @@ -42,3 +130,13 @@ BOOL WINAPI EditSecurity(HWND owner, LPSECURITYINFO psi) FIXME("(%p, %p): stub\n", owner, psi); return FALSE; } + +BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) +{ + if (reason == DLL_PROCESS_ATTACH) + { + aclui_instance = instance; + DisableThreadLibraryCalls(instance); + } + return TRUE; +} diff --git a/dlls/aclui/resource.h b/dlls/aclui/resource.h new file mode 100644 index 00000000000..f92d99692c7 --- /dev/null +++ b/dlls/aclui/resource.h @@ -0,0 +1,36 @@ +/* + * Definitions for aclui dialog controls + * + * Copyright (c) 2017 Michael Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_ACLUI__ +#define __WINE_ACLUI__ + +#define IDD_SECURITY_PROPERTIES 100 + +#define IDC_USERS 101 + +#define IDC_ACE_USER 110 +#define IDC_ACE 111 + +#define IDS_PERMISSION_FOR 1000 + +#define IDB_USER_ICONS 2000 +#define IDB_CHECKBOX 2001 + +#endif /* __WINE_ACLUI__ */
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; }
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.rc | 5 +++++ dlls/aclui/aclui_main.c | 34 +++++++++++++++++++++++++++++++++- dlls/aclui/user_icons.bmp | Bin 0 -> 2730 bytes 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 dlls/aclui/user_icons.bmp
diff --git a/dlls/aclui/Makefile.in b/dlls/aclui/Makefile.in index f93e5da6c8d..1eac32f0700 100644 --- a/dlls/aclui/Makefile.in +++ b/dlls/aclui/Makefile.in @@ -1,6 +1,6 @@ MODULE = aclui.dll IMPORTLIB = aclui -IMPORTS = comctl32 user32 advapi32 +IMPORTS = comctl32 user32 advapi32 gdi32
EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native
diff --git a/dlls/aclui/aclui.rc b/dlls/aclui/aclui.rc index 3a03b0550e9..6e6b3c268b5 100644 --- a/dlls/aclui/aclui.rc +++ b/dlls/aclui/aclui.rc @@ -36,3 +36,8 @@ BEGIN LTEXT "Deny", -1, 180, 105, 55, 10, SS_CENTER 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 + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +/* @makedep: user_icons.bmp */ +IDB_USER_ICONS BITMAP user_icons.bmp diff --git a/dlls/aclui/aclui_main.c b/dlls/aclui/aclui_main.c index 199e7295adc..01e3476b97f 100644 --- a/dlls/aclui/aclui_main.c +++ b/dlls/aclui/aclui_main.c @@ -55,6 +55,7 @@ struct security_page unsigned int user_count;
HWND dialog; + HIMAGELIST image_list; };
static HINSTANCE aclui_instance; @@ -110,11 +111,12 @@ static void add_user(struct security_page *page, PSID sid) user->name = name; user->sid = sid;
- item.mask = LVIF_PARAM | LVIF_TEXT; + item.mask = LVIF_PARAM | LVIF_TEXT | LVIF_IMAGE; item.iItem = -1; item.iSubItem = 0; item.pszText = name; item.lParam = (LPARAM)user; + item.iImage = (sid_type == SidTypeGroup || sid_type == SidTypeWellKnownGroup) ? 0 : 1;
SendMessageW(GetDlgItem(page->dialog, IDC_USERS), LVM_INSERTITEMW, 0, (LPARAM)&item); } @@ -160,6 +162,30 @@ static void init_users(struct security_page *page) } }
+static HIMAGELIST create_image_list(UINT resource, UINT width, UINT height, UINT count, COLORREF mask_color) +{ + HIMAGELIST image_list; + HBITMAP image; + INT ret; + + if (!(image_list = ImageList_Create(width, height, ILC_COLOR32 | ILC_MASK, 0, count))) + return NULL; + if (!(image = LoadBitmapW(aclui_instance, MAKEINTRESOURCEW(resource)))) + { + ImageList_Destroy(image_list); + return NULL; + } + + ret = ImageList_AddMasked(image_list, image, mask_color); + DeleteObject(image); + if (ret == -1) + { + ImageList_Destroy(image_list); + return NULL; + } + return image_list; +} + static void security_page_free(struct security_page *page) { unsigned int i; @@ -169,6 +195,8 @@ static void security_page_free(struct security_page *page) free(page->users);
LocalFree(page->sd); + if (page->image_list) + ImageList_Destroy(page->image_list); if (page->security) ISecurityInformation_Release(page->security); free(page); @@ -199,6 +227,10 @@ static void security_page_init_dlg(HWND hwnd, struct security_page *page) column.cx = rect.right - rect.left; SendMessageW(control, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
+ if (!(page->image_list = create_image_list(IDB_USER_ICONS, 18, 18, 2, RGB(255, 0, 255)))) + return; + SendMessageW(control, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)page->image_list); + init_users(page);
if (page->user_count) diff --git a/dlls/aclui/user_icons.bmp b/dlls/aclui/user_icons.bmp new file mode 100644 index 0000000000000000000000000000000000000000..29259e2724ccf67b7e3e84c3fc6d749bc9e8ae26 GIT binary patch literal 2730 zcmdUtc~F#P0LH1N8IS3YY|3(`$+FC$Q3M3!8WF=I!cj3Jj^t)pSCB(Uu2clUR2&33 zmt$E#SWXd>M2$=FNK;cX1Ox;D6*{J|rkY>xw}vCAo72=EeY4NL`+nd1{Py{t_qBB> zousF|c8KpNp*Mx52tB1YUGEt&P8ZJ&pS>qB9lg-gyZ_O%U9u`<^ud#kPmfy&di<}{ zakhb0O*)MQyY8!{B!$ke8g;%$TT?AHpKYKjQ9<Q)`9rGS5x~WIjZVh+t~9YeWct~V zEwe@`w-H)Mmdu6>KWlM+A%)TIkK`T6*g}5L`zZYvknL+p)?dmLW4gBmX<im&3QoGe z9hD;2`2T&>{G?_dsa{rOyBm_@A>?UD@ut;exz8p2V*`?1=8)iGhP3WM|43gK1tH7D z8bj?`$*&atY)>N!!&Z{9b}ngd2BZl8)|L9C$rjUnv2_eX;$7(MM3$P2bJ7mhChsOT z=mS(TbJRY@6#LC%zs!Utv2O)po-5eN&a=t#v*MUCZVaonEFE>gyQI1rpz=1>`qjSk z(1bfsn;cG_mytG~lq=p*pDej8P3ojEj2pLaVHO&|OY6Ov?B~V=9~T_mY|#WQL?bt) zYP}h?p*9TO?4xFrJ%xfVWy(|7^3BomF{~!lPD(-+YqOMycaZ#LLdVm>Idf1&k$5*L zr_`C0DQBH6m+H&LFk;ksOk3y41SyOES|-TdnIdy0dA*&;V$RV|9jHu{Q+uqL^3Q@f z6yt!}-<-;AK4Umi&wW?VQyR9MQhyUF6lNR<m``n>IUT3!80_s7`OHM$Cggh?k>h28 zI&>v>bAK4a3Cqpm<q$a&6&_3s^kHI<uU0lb4itsj;}(&C_3lPYQZ8V%rx};XM9O1a z8S1<;hBJDODz|!aV51$?qSyKudy0aW(A?BWbIS?xLsw82>!|HWx_>As^dUy|$rfgQ z5_m7iMmdusH!x|VKa;{0%naI$S!Nq^vaX|_ah;iIU6?7`*?r{lL!8k(BmLcIBGynF zX2<4D3M^wQuuMKJbOwvKgKUWoK@+-+k_hL=GS=*j<CVxDCIoo#f?oj7Ir{Rvhscw7 zn5Fw~;9fI;OVv%RRlU5O-i4dy+GAN#uG>BB1c!%VnsgGA+-_zGkK{AX>BfBTSv(`R z^T+hxAIrGw{wwxzo0;kq%5=X}UXy3?x;z7;T_^B8G{~M)BgD7d;ls+Cyd^qvEbe$L zYqY1unO|d`-=lp88+9+HBA4WyExKNmed%xg5y~3gP-HVBxR4n^g-rEHV^-X86m>)F zJu^bWiD8^Xp4pk#kyUl+<el&Ti3K_BIF$C`T|0pP=YxDCyjH3nZKnCk4%Fucbuyf` z7c(cOTAbY`tadh_zp0!TWlC()&!Z4L53y&<if{0qs-4S&KkH<D@!cJks=KsV;#-E< zb9#i0M{lu0)5k1v4$X6~lW@FOC&P7@28+aFtWvkLJg<#;+v=Dm%fvdWfT$xqC~CTh zsO#p&_rK`mNc+_@a+ei_9jrS%NV3SHy7(heU*2YQc|Y%nel2r4sBa(E$w{hcz$*SA zcKgn<DCIN;F$Z|nKLbT-l}_L2c^N;tmRv=4Xn-)$OLW6+?Vc?a{hH?X;Gk-IB4%KE z4dzk%F^;Z8e}fXI_@XEBjn5*@hns%GvET}BmA!Z#9AHgFKeh$kEX!@<+acZi{UEQs mZ-|`3t(<G``Nvrv<n3+g$E*Ar9%a|qcJ$w2KFI$MfBy-k@DaHH
literal 0 HcmV?d00001
From: Michael Müller michael@fds-team.de
Signed-off-by: Zebediah Figura z.figura12@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 01e3476b97f..24fb32fdb8c 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; }
From: Michael Müller michael@fds-team.de
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/aclui/aclui_main.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/dlls/aclui/aclui_main.c b/dlls/aclui/aclui_main.c index 24fb32fdb8c..43171d70410 100644 --- a/dlls/aclui/aclui_main.c +++ b/dlls/aclui/aclui_main.c @@ -480,10 +480,32 @@ HPROPSHEETPAGE WINAPI CreateSecurityPage(ISecurityInformation *security) return ret; }
-BOOL WINAPI EditSecurity(HWND owner, LPSECURITYINFO psi) +BOOL WINAPI EditSecurity(HWND owner, ISecurityInformation *security) { - FIXME("(%p, %p): stub\n", owner, psi); - return FALSE; + PROPSHEETHEADERW sheet = {0}; + HPROPSHEETPAGE pages[1]; + SI_OBJECT_INFO info; + BOOL ret; + + TRACE("(%p, %p)\n", owner, security); + + if (FAILED(ISecurityInformation_GetObjectInformation(security, &info))) + return FALSE; + if (!(pages[0] = CreateSecurityPage(security))) + return FALSE; + + sheet.dwSize = sizeof(sheet); + sheet.dwFlags = PSH_DEFAULT; + sheet.hwndParent = owner; + sheet.hInstance = aclui_instance; + sheet.pszCaption = load_formatstr(IDS_PERMISSION_FOR, info.pszObjectName); + sheet.nPages = 1; + sheet.nStartPage = 0; + sheet.phpage = pages; + + ret = PropertySheetW(&sheet) != -1; + LocalFree((void *)sheet.pszCaption); + return ret; }
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)