[PATCH 2/2] shell32: Add security property tab.
Zebediah Figura
z.figura12 at gmail.com
Wed Feb 17 23:32:17 CST 2021
From: Michael Müller <michael at fds-team.de>
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/shell32/Makefile.in | 2 +-
dlls/shell32/shell32.rc | 20 +++
dlls/shell32/shlview_cmenu.c | 302 +++++++++++++++++++++++++++++++++++
dlls/shell32/shresdef.h | 20 +++
4 files changed, 343 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index fe49bf09f98..f6fcf2e18eb 100644
--- a/dlls/shell32/Makefile.in
+++ b/dlls/shell32/Makefile.in
@@ -1,7 +1,7 @@
EXTRADEFS = -D_SHELL32_
MODULE = shell32.dll
IMPORTLIB = shell32
-IMPORTS = uuid shlwapi user32 gdi32 advapi32
+IMPORTS = uuid shlwapi user32 gdi32 advapi32 aclui
DELAYIMPORTS = ole32 oleaut32 shdocvw version comctl32 gdiplus
# AUTHORS file is in the top-level directory
EXTRAINCL = -I$(top_srcdir)
diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc
index f19b09f8c21..ce5daea1e8b 100644
--- a/dlls/shell32/shell32.rc
+++ b/dlls/shell32/shell32.rc
@@ -197,6 +197,26 @@ the folder?"
IDS_RUNDLG_BROWSE_FILTER_EXE "Executable files (*.exe)"
IDS_RUNDLG_BROWSE_FILTER_ALL "All files (*.*)"
+ IDS_SECURITY_ADD_FILE "Add File"
+ IDS_SECURITY_ADD_SUBDIRECTORY "Add Subdirectory"
+ IDS_SECURITY_ALL_ACCESS "All Access"
+ IDS_SECURITY_APPEND_DATA "Append Data"
+ IDS_SECURITY_DELETE "Delete"
+ IDS_SECURITY_DELETE_CHILD "Delete Child"
+ IDS_SECURITY_EXECUTE "Execute"
+ IDS_SECURITY_LIST_DIRECTORY "List Directory Contents"
+ IDS_SECURITY_READ_ATTRIBUTES "Read Attributes"
+ IDS_SECURITY_READ_CONTROL "Read Security Descriptor"
+ IDS_SECURITY_READ_DATA "Read Data"
+ IDS_SECURITY_READ_EA "Read Extended Attributes"
+ IDS_SECURITY_SYNCHRONIZE "Synchronize"
+ IDS_SECURITY_TRAVERSE "Traverse"
+ IDS_SECURITY_WRITE_ATTRIBUTES "Write Attributes"
+ IDS_SECURITY_WRITE_DAC "Write DACL"
+ IDS_SECURITY_WRITE_DATA "Write Data"
+ IDS_SECURITY_WRITE_EA "Write Extended Attributes"
+ IDS_SECURITY_WRITE_OWNER "Write Owner"
+
/* shell folder path default values */
/* FIXME: Some will be unused until desktop.ini support is implemented */
IDS_PROGRAMS "Programs"
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index 04ac0b6fd3c..86b84a3ca67 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -39,12 +39,68 @@
#include "shresdef.h"
#include "shlwapi.h"
+#include "initguid.h"
+#include "aclui.h"
+#include "aclapi.h"
#include "wine/heap.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+#define X(a, b) {&GUID_NULL, a, MAKEINTRESOURCEW(b), SI_ACCESS_GENERAL},
+
+static const SI_ACCESS access_rights_file[] =
+{
+ X(FILE_ALL_ACCESS, IDS_SECURITY_ALL_ACCESS)
+ X(FILE_READ_DATA, IDS_SECURITY_READ_DATA)
+ X(FILE_WRITE_DATA, IDS_SECURITY_WRITE_DATA)
+ X(FILE_APPEND_DATA, IDS_SECURITY_APPEND_DATA)
+ X(FILE_READ_EA, IDS_SECURITY_READ_EA)
+ X(FILE_WRITE_EA, IDS_SECURITY_WRITE_EA)
+ X(FILE_EXECUTE, IDS_SECURITY_EXECUTE)
+ X(FILE_READ_ATTRIBUTES, IDS_SECURITY_READ_ATTRIBUTES)
+ X(FILE_WRITE_ATTRIBUTES, IDS_SECURITY_WRITE_ATTRIBUTES)
+ X(DELETE, IDS_SECURITY_DELETE)
+ X(READ_CONTROL, IDS_SECURITY_READ_CONTROL)
+ X(WRITE_DAC, IDS_SECURITY_WRITE_DAC)
+ X(WRITE_OWNER, IDS_SECURITY_WRITE_OWNER)
+ X(SYNCHRONIZE, IDS_SECURITY_SYNCHRONIZE)
+};
+
+static const SI_ACCESS access_rights_directory[] =
+{
+ X(FILE_ALL_ACCESS, IDS_SECURITY_ALL_ACCESS)
+ X(FILE_LIST_DIRECTORY, IDS_SECURITY_LIST_DIRECTORY)
+ X(FILE_ADD_FILE, IDS_SECURITY_ADD_FILE)
+ X(FILE_ADD_SUBDIRECTORY, IDS_SECURITY_ADD_SUBDIRECTORY)
+ X(FILE_READ_EA, IDS_SECURITY_READ_EA)
+ X(FILE_WRITE_EA, IDS_SECURITY_WRITE_EA)
+ X(FILE_TRAVERSE, IDS_SECURITY_TRAVERSE)
+ X(FILE_DELETE_CHILD, IDS_SECURITY_DELETE_CHILD)
+ X(FILE_READ_ATTRIBUTES, IDS_SECURITY_READ_ATTRIBUTES)
+ X(FILE_WRITE_ATTRIBUTES, IDS_SECURITY_WRITE_ATTRIBUTES)
+ X(DELETE, IDS_SECURITY_DELETE)
+ X(READ_CONTROL, IDS_SECURITY_READ_CONTROL)
+ X(WRITE_DAC, IDS_SECURITY_WRITE_DAC)
+ X(WRITE_OWNER, IDS_SECURITY_WRITE_OWNER)
+ X(SYNCHRONIZE, IDS_SECURITY_SYNCHRONIZE)
+};
+#undef X
+
+struct security_info
+{
+ ISecurityInformation ISecurityInformation_iface;
+ LONG refcount;
+ WCHAR *path;
+ BOOL directory;
+};
+
+static inline struct security_info *impl_from_ISecurityInformation(ISecurityInformation *iface)
+{
+ return CONTAINING_RECORD(iface, struct security_info, ISecurityInformation_iface);
+}
+
typedef struct
{
IContextMenu3 IContextMenu3_iface;
@@ -615,6 +671,251 @@ error:
heap_free(props);
}
+static HRESULT WINAPI security_info_QueryInterface(ISecurityInformation *iface, REFIID iid, void **out)
+{
+ TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
+
+ if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_ISecurityInformation))
+ {
+ IUnknown_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+ else
+ {
+ *out = NULL;
+ WARN("%s is not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+ return E_NOINTERFACE;
+ }
+}
+
+static ULONG WINAPI security_info_AddRef(ISecurityInformation *iface)
+{
+ struct security_info *info = impl_from_ISecurityInformation(iface);
+ ULONG refcount = InterlockedIncrement(&info->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI security_info_Release(ISecurityInformation *iface)
+{
+ struct security_info *info = impl_from_ISecurityInformation(iface);
+ ULONG refcount = InterlockedIncrement(&info->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ HeapFree(GetProcessHeap(), 0, info->path);
+ HeapFree(GetProcessHeap(), 0, info);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI security_info_GetObjectInformation(ISecurityInformation *iface, SI_OBJECT_INFO *out)
+{
+ struct security_info *info = impl_from_ISecurityInformation(iface);
+
+ TRACE("iface %p, out %p.\n", iface, out);
+
+ memset(out, 0, sizeof(*out));
+ out->dwFlags = SI_ADVANCED;
+ out->hInstance = shell32_hInstance;
+ out->pszObjectName = info->path;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI security_info_GetSecurity(ISecurityInformation *iface,
+ SECURITY_INFORMATION mask, PSECURITY_DESCRIPTOR *sd, BOOL default_sd)
+{
+ struct security_info *info = impl_from_ISecurityInformation(iface);
+
+ TRACE("iface %p, mask %#x, sd %p, default_sd %d.\n", iface, mask, sd, default_sd);
+
+ if (default_sd)
+ FIXME("Returning a default security descriptor is not implemented.\n");
+
+ return HRESULT_FROM_WIN32(GetNamedSecurityInfoW(info->path, SE_FILE_OBJECT,
+ mask, NULL, NULL, NULL, NULL, sd));
+}
+
+static HRESULT WINAPI security_info_SetSecurity(ISecurityInformation *iface,
+ SECURITY_INFORMATION mask, PSECURITY_DESCRIPTOR sd)
+{
+ struct security_info *info = impl_from_ISecurityInformation(iface);
+ BOOL present, defaulted;
+ PSID owner, group;
+ ACL *dacl, *sacl;
+
+ TRACE("iface %p, mask %#x, sd %p.\n", iface, mask, sd);
+
+ if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted))
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ if (!GetSecurityDescriptorGroup(sd, &group, &defaulted))
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ if (!GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted))
+ return HRESULT_FROM_WIN32(GetLastError());
+ if (!present) dacl = NULL;
+
+ if (!GetSecurityDescriptorSacl(sd, &present, &sacl, &defaulted))
+ return HRESULT_FROM_WIN32(GetLastError());
+ if (!present) sacl = NULL;
+
+ return HRESULT_FROM_WIN32(SetNamedSecurityInfoW(info->path, SE_FILE_OBJECT,
+ mask, owner, group, dacl, sacl));
+}
+
+static HRESULT WINAPI security_info_GetAccessRights(ISecurityInformation *iface,
+ const GUID *type, DWORD flags, SI_ACCESS **access, ULONG *count, ULONG *default_access )
+{
+ struct security_info *info = impl_from_ISecurityInformation(iface);
+
+ TRACE("info %p, type %s, flags %#x, access %p, count %p, default_access %p.\n",
+ info, debugstr_guid(type), flags, access, count, default_access);
+
+ if (info->directory)
+ {
+ *access = (SI_ACCESS *)access_rights_directory;
+ *count = ARRAY_SIZE(access_rights_directory);
+ }
+ else
+ {
+ *access = (SI_ACCESS *)access_rights_file;
+ *count = ARRAY_SIZE(access_rights_file);
+ }
+
+ *default_access = 0;
+ return S_OK;
+}
+
+static HRESULT WINAPI security_info_MapGeneric(ISecurityInformation *iface,
+ const GUID *type, UCHAR *ace_flags, ACCESS_MASK *mask)
+{
+ GENERIC_MAPPING map =
+ {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE,
+ FILE_GENERIC_EXECUTE,
+ FILE_ALL_ACCESS
+ };
+
+ TRACE("iface %p, type %s, ace_flags %p, mask %p.\n", iface, debugstr_guid(type), ace_flags, mask);
+
+ MapGenericMask(mask, &map);
+ return S_OK;
+}
+
+static HRESULT WINAPI security_info_GetInheritTypes(ISecurityInformation *iface,
+ SI_INHERIT_TYPE **types, ULONG *count)
+{
+ FIXME("iface %p, types %p, count %p, stub!\n", iface, types, count);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI security_info_PropertySheetPageCallback(ISecurityInformation *iface,
+ HWND hwnd, UINT msg, SI_PAGE_TYPE page)
+{
+ TRACE("iface %p, hwnd %p, msg %#x, page %#x.\n", iface, hwnd, msg, page);
+ return S_OK;
+}
+
+static const struct ISecurityInformationVtbl security_info_vtbl =
+{
+ security_info_QueryInterface,
+ security_info_AddRef,
+ security_info_Release,
+ security_info_GetObjectInformation,
+ security_info_GetSecurity,
+ security_info_SetSecurity,
+ security_info_GetAccessRights,
+ security_info_MapGeneric,
+ security_info_GetInheritTypes,
+ security_info_PropertySheetPageCallback,
+};
+
+static ISecurityInformation *create_security_info(WCHAR *path, BOOL directory)
+{
+ struct security_info *security;
+ DWORD len;
+
+ if (!(security = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*security))))
+ return NULL;
+
+ security->ISecurityInformation_iface.lpVtbl = &security_info_vtbl;
+ security->refcount = 1;
+ security->directory = directory;
+
+ len = (strlenW(path) + 1) * sizeof(WCHAR);
+ security->path = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!security->path)
+ {
+ HeapFree(GetProcessHeap(), 0, security);
+ return NULL;
+ }
+
+ memcpy(security->path, path, len);
+ return &security->ISecurityInformation_iface;
+}
+
+static void init_security_properties_pages(IDataObject *pDo, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
+{
+ ISecurityInformation *security;
+ HPROPSHEETPAGE security_page;
+ FORMATETC format;
+ STGMEDIUM stgm;
+ DWORD attrib;
+ WCHAR *path;
+ UINT len;
+
+ format.cfFormat = CF_HDROP;
+ format.ptd = NULL;
+ format.dwAspect = DVASPECT_CONTENT;
+ format.lindex = -1;
+ format.tymed = TYMED_HGLOBAL;
+
+ if (FAILED(IDataObject_GetData(pDo, &format, &stgm)))
+ return;
+
+ if (!(len = DragQueryFileW((HDROP)stgm.DUMMYUNIONNAME.hGlobal, 0, NULL, 0)))
+ {
+ ReleaseStgMedium(&stgm);
+ return;
+ }
+
+ if (!(path = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR))))
+ {
+ ReleaseStgMedium(&stgm);
+ return;
+ }
+
+ len = DragQueryFileW((HDROP)stgm.DUMMYUNIONNAME.hGlobal, 0, path, len + 1);
+ ReleaseStgMedium(&stgm);
+ if (!len) goto done;
+
+ attrib = GetFileAttributesW(path);
+ if (attrib == INVALID_FILE_ATTRIBUTES)
+ goto done;
+
+ if (!(security = create_security_info(path, !!(attrib & FILE_ATTRIBUTE_DIRECTORY))))
+ goto done;
+
+ security_page = CreateSecurityPage(security);
+ IUnknown_Release((IUnknown *)security);
+ if (!security_page) goto done;
+
+ lpfnAddPage(security_page, lParam);
+
+done:
+ HeapFree(GetProcessHeap(), 0, path);
+}
+
+
#define MAX_PROP_PAGES 99
static void DoOpenProperties(ContextMenu *This, HWND hwnd)
@@ -697,6 +998,7 @@ static void DoOpenProperties(ContextMenu *This, HWND hwnd)
if (SUCCEEDED(ret))
{
init_file_properties_pages(lpDo, Properties_AddPropSheetCallback, (LPARAM)&psh);
+ init_security_properties_pages(lpDo, Properties_AddPropSheetCallback, (LPARAM)&psh);
hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletype, MAX_PROP_PAGES - psh.nPages, lpDo);
if (hpsxa != NULL)
diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h
index 92185d637e7..dfbe7d8588b 100644
--- a/dlls/shell32/shresdef.h
+++ b/dlls/shell32/shresdef.h
@@ -149,6 +149,26 @@
#define IDM_RECYCLEBIN_RESTORE 301
#define IDM_RECYCLEBIN_ERASE 302
+#define IDS_SECURITY_ADD_FILE 400
+#define IDS_SECURITY_ADD_SUBDIRECTORY 401
+#define IDS_SECURITY_ALL_ACCESS 402
+#define IDS_SECURITY_APPEND_DATA 403
+#define IDS_SECURITY_DELETE 404
+#define IDS_SECURITY_DELETE_CHILD 405
+#define IDS_SECURITY_EXECUTE 406
+#define IDS_SECURITY_LIST_DIRECTORY 407
+#define IDS_SECURITY_READ_ATTRIBUTES 408
+#define IDS_SECURITY_READ_CONTROL 409
+#define IDS_SECURITY_READ_DATA 410
+#define IDS_SECURITY_READ_EA 411
+#define IDS_SECURITY_SYNCHRONIZE 412
+#define IDS_SECURITY_TRAVERSE 413
+#define IDS_SECURITY_WRITE_ATTRIBUTES 414
+#define IDS_SECURITY_WRITE_DAC 415
+#define IDS_SECURITY_WRITE_DATA 416
+#define IDS_SECURITY_WRITE_EA 417
+#define IDS_SECURITY_WRITE_OWNER 418
+
/* Note: this string is referenced from the registry*/
#define IDS_RECYCLEBIN_FOLDER_NAME 8964
--
2.30.1
More information about the wine-devel
mailing list