Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
February 2021
- 81 participants
- 1707 messages
[PATCH v2 2/2] ntdll: Allow getting/setting x86_64 context of x86 processes in wine64
by Rafał Harabień
WoW64 process has two separate contexts:
- x86 context used most of the time (e.g. by application code)
- x86_64 context used by system when it quits x86 emulation and jumps to
the kernel code
A notable exception are debug registers - their state is shared. Some
debuggers make use of that fact and sets/gets debug registers of x86
processes using x86_64 thread context.
This change adds support for setting and getting debug registers using
x86_64 thread context. Getting other registers is allowed too and will
return values from x86 thread context.
This change fixes hardware breakpoints in IDA 7.0 disassembler (x86_64 app)
when debugging x86 (32 bit) applications.
Signed-off-by: Rafał Harabień <rafalh92(a)outlook.com>
---
dlls/ntdll/tests/exception.c | 9 -----
dlls/ntdll/unix/signal_x86_64.c | 62 +++++++++++++++++++++++++++++++++
server/thread.c | 24 +++++++++++--
3 files changed, 84 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 8f83a14f856..1eaadf9d01e 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -5841,7 +5841,6 @@ static void test_debug_registers_wow64(void)
ZeroMemory(&ctx, sizeof(ctx));
ctx.ContextFlags = CONTEXT_ALL;
bret = GetThreadContext(pi.hThread, &ctx);
- todo_wine
ok(bret, "GetThreadContext failed\n");
ctx.Dr0 = 0x12340000;
@@ -5850,14 +5849,12 @@ static void test_debug_registers_wow64(void)
ctx.Dr3 = 0x12340003;
ctx.Dr7 = 0x155; // enable all breakpoints (local)
bret = SetThreadContext(pi.hThread, &ctx);
- todo_wine
ok(bret, "SetThreadContext failed\n");
if (bret) {
ZeroMemory(&ctx, sizeof(ctx));
ctx.ContextFlags = CONTEXT_ALL;
bret = GetThreadContext(pi.hThread, &ctx);
- todo_wine
ok(bret, "GetThreadContext failed\n");
if (bret)
{
@@ -5896,22 +5893,16 @@ static void test_debug_registers_wow64(void)
ok(ret == STATUS_SUCCESS, "Wow64GetThreadContext failed with %lx\n", ret);
if (ret == STATUS_SUCCESS)
{
- todo_wine
ok(wow64_ctx.Dr0 == 0x56780000, "expected 0x56780000, got %lx\n", wow64_ctx.Dr0);
- todo_wine
ok(wow64_ctx.Dr1 == 0x56780001, "expected 0x56780001, got %lx\n", wow64_ctx.Dr1);
- todo_wine
ok(wow64_ctx.Dr2 == 0x56780002, "expected 0x56780002, got %lx\n", wow64_ctx.Dr2);
- todo_wine
ok(wow64_ctx.Dr3 == 0x56780003, "expected 0x56780003, got %lx\n", wow64_ctx.Dr3);
- todo_wine
ok(wow64_ctx.Dr7 == 0x101, "expected 0x101, got %lx\n", wow64_ctx.Dr7);
}
ZeroMemory(&ctx, sizeof(ctx));
ctx.ContextFlags = CONTEXT_ALL;
bret = GetThreadContext(pi.hThread, &ctx);
- todo_wine
ok(bret, "GetThreadContext failed\n");
if (bret)
{
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index e62e958b4aa..51b324a1790 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -1707,6 +1707,68 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
*/
NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
+ if (from->cpu == CPU_x86)
+ {
+ // WoW64 process has two separate contexts: one 32 bit used when executing normal user code and one 64 bit
+ // used by WoW64 internals for talking with the kernel. Debug registers are shared between those contexts
+ // and some debuggers make use of that fact so handle getting them here. Other registers could be set to
+ // anything but to keep things sane lets copy them from 32 bit context.
+ to->ContextFlags = CONTEXT_AMD64;
+ if (from->flags & SERVER_CTX_CONTROL)
+ {
+ to->ContextFlags |= CONTEXT_CONTROL;
+ to->Rbp = from->ctl.i386_regs.ebp;
+ to->Rip = from->ctl.i386_regs.eip;
+ to->Rsp = from->ctl.i386_regs.esp;
+ to->SegCs = from->ctl.i386_regs.cs;
+ to->SegSs = from->ctl.i386_regs.ss;
+ to->EFlags = from->ctl.i386_regs.eflags;
+ }
+
+ if (from->flags & SERVER_CTX_INTEGER)
+ {
+ to->ContextFlags |= CONTEXT_INTEGER;
+ to->Rax = from->integer.i386_regs.eax;
+ to->Rcx = from->integer.i386_regs.ecx;
+ to->Rdx = from->integer.i386_regs.edx;
+ to->Rbx = from->integer.i386_regs.ebx;
+ to->Rsi = from->integer.i386_regs.esi;
+ to->Rdi = from->integer.i386_regs.edi;
+ to->R8 = 0;
+ to->R9 = 0;
+ to->R10 = 0;
+ to->R11 = 0;
+ to->R12 = 0;
+ to->R13 = 0;
+ to->R14 = 0;
+ to->R15 = 0;
+ }
+ if (from->flags & SERVER_CTX_SEGMENTS)
+ {
+ to->ContextFlags |= CONTEXT_SEGMENTS;
+ to->SegDs = from->seg.i386_regs.ds;
+ to->SegEs = from->seg.i386_regs.es;
+ to->SegFs = from->seg.i386_regs.fs;
+ to->SegGs = from->seg.i386_regs.gs;
+ }
+ if (from->flags & SERVER_CTX_FLOATING_POINT)
+ {
+ to->ContextFlags |= CONTEXT_FLOATING_POINT;
+ memset(&to->u.FltSave, 0, sizeof(to->u.FltSave));
+ }
+ if (from->flags & SERVER_CTX_DEBUG_REGISTERS)
+ {
+ to->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
+ to->Dr0 = from->debug.i386_regs.dr0;
+ to->Dr1 = from->debug.i386_regs.dr1;
+ to->Dr2 = from->debug.i386_regs.dr2;
+ to->Dr3 = from->debug.i386_regs.dr3;
+ to->Dr6 = from->debug.i386_regs.dr6;
+ to->Dr7 = from->debug.i386_regs.dr7;
+ }
+ return STATUS_SUCCESS;
+ }
+
if (from->cpu != CPU_x86_64) return STATUS_INVALID_PARAMETER;
to->ContextFlags = CONTEXT_AMD64 | (to->ContextFlags & 0x40);
diff --git a/server/thread.c b/server/thread.c
index d544970f3c1..281ad93a849 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -1890,8 +1890,7 @@ DECL_HANDLER(set_thread_context)
reply->self = (thread == current);
if (thread->state == TERMINATED) set_error( STATUS_UNSUCCESSFUL );
- else if (context->cpu != thread->process->cpu) set_error( STATUS_INVALID_PARAMETER );
- else
+ else if (context->cpu == thread->process->cpu)
{
unsigned int system_flags = get_context_system_regs(context->cpu) & context->flags;
@@ -1903,6 +1902,27 @@ DECL_HANDLER(set_thread_context)
thread->context->regs.flags |= context->flags;
}
}
+ else if (context->cpu == CPU_x86_64 && thread->process->cpu == CPU_x86)
+ {
+ // WoW64 process has two separate contexts: one 32 bit used when executing normal user code and one 64 bit
+ // used by WoW64 internals for talking with the kernel. Debug registers are shared between those contexts
+ // and some debuggers make use of that fact so handle setting them here.
+ unsigned int system_flags = get_context_system_regs( context->cpu ) & context->flags;
+ if (system_flags)
+ {
+ set_thread_context( thread, context, system_flags );
+ if (thread->context && !get_error())
+ {
+ thread->context->regs.debug.i386_regs.dr0 = context->debug.x86_64_regs.dr0;
+ thread->context->regs.debug.i386_regs.dr1 = context->debug.x86_64_regs.dr1;
+ thread->context->regs.debug.i386_regs.dr2 = context->debug.x86_64_regs.dr2;
+ thread->context->regs.debug.i386_regs.dr3 = context->debug.x86_64_regs.dr3;
+ thread->context->regs.debug.i386_regs.dr6 = context->debug.x86_64_regs.dr6;
+ thread->context->regs.debug.i386_regs.dr7 = context->debug.x86_64_regs.dr7;
+ }
+ }
+ }
+ else set_error( STATUS_INVALID_PARAMETER );
release_object( thread );
}
--
2.25.1
Feb. 28, 2021
[PATCH v2 1/2] ntdll/tests: test getting/setting x86_64 context of x86 processes in wine64
by Rafał Harabień
Signed-off-by: Rafał Harabień <rafalh92(a)outlook.com>
---
dlls/ntdll/tests/exception.c | 115 +++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 397de7dad98..8f83a14f856 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -5816,6 +5816,120 @@ static void test_debug_registers(void)
CloseHandle(thread);
}
+#if defined(__x86_64__)
+
+static void test_debug_registers_wow64(void)
+{
+ char cmdline[] = "C:\\windows\\syswow64\\notepad.exe";
+ PROCESS_INFORMATION pi;
+ STARTUPINFOA si = {0};
+ WOW64_CONTEXT wow64_ctx;
+ CONTEXT ctx;
+ BOOL is_wow64;
+ NTSTATUS ret;
+ BOOL bret;
+
+ si.cb = sizeof(si);
+ bret = CreateProcessA(cmdline, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+ ok(bret, "CreateProcessA failed\n");
+
+ bret = pIsWow64Process(pi.hProcess, &is_wow64);
+ ok(bret && is_wow64, "expected Wow64 process\n");
+
+ SuspendThread(pi.hThread);
+
+ ZeroMemory(&ctx, sizeof(ctx));
+ ctx.ContextFlags = CONTEXT_ALL;
+ bret = GetThreadContext(pi.hThread, &ctx);
+ todo_wine
+ ok(bret, "GetThreadContext failed\n");
+
+ ctx.Dr0 = 0x12340000;
+ ctx.Dr1 = 0x12340001;
+ ctx.Dr2 = 0x12340002;
+ ctx.Dr3 = 0x12340003;
+ ctx.Dr7 = 0x155; // enable all breakpoints (local)
+ bret = SetThreadContext(pi.hThread, &ctx);
+ todo_wine
+ ok(bret, "SetThreadContext failed\n");
+
+ if (bret) {
+ ZeroMemory(&ctx, sizeof(ctx));
+ ctx.ContextFlags = CONTEXT_ALL;
+ bret = GetThreadContext(pi.hThread, &ctx);
+ todo_wine
+ ok(bret, "GetThreadContext failed\n");
+ if (bret)
+ {
+ ok(ctx.Dr0 == 0x12340000, "expected 0x12340000, got %lx\n", ctx.Dr0);
+ ok(ctx.Dr1 == 0x12340001, "expected 0x12340001, got %lx\n", ctx.Dr1);
+ ok(ctx.Dr2 == 0x12340002, "expected 0x12340002, got %lx\n", ctx.Dr2);
+ ok(ctx.Dr3 == 0x12340003, "expected 0x12340003, got %lx\n", ctx.Dr3);
+ ok(ctx.Dr7 == 0x155, "expected 0x155, got %lx\n", ctx.Dr7);
+ }
+
+ ZeroMemory(&wow64_ctx, sizeof(wow64_ctx));
+ wow64_ctx.ContextFlags = WOW64_CONTEXT_ALL;
+ ret = pRtlWow64GetThreadContext(pi.hThread, &wow64_ctx);
+ ok(ret == STATUS_SUCCESS, "Wow64GetThreadContext failed with %lx\n", ret);
+ if (ret == STATUS_SUCCESS)
+ {
+ ok(wow64_ctx.Dr0 == 0x12340000, "expected 0x12340000, got %lx\n", wow64_ctx.Dr0);
+ ok(wow64_ctx.Dr1 == 0x12340001, "expected 0x12340001, got %lx\n", wow64_ctx.Dr1);
+ ok(wow64_ctx.Dr2 == 0x12340002, "expected 0x12340002, got %lx\n", wow64_ctx.Dr2);
+ ok(wow64_ctx.Dr3 == 0x12340003, "expected 0x12340003, got %lx\n", wow64_ctx.Dr3);
+ ok(wow64_ctx.Dr7 == 0x155, "expected 0x155, got %lx\n", wow64_ctx.Dr7);
+ }
+ }
+
+ wow64_ctx.Dr0 = 0x56780000;
+ wow64_ctx.Dr1 = 0x56780001;
+ wow64_ctx.Dr2 = 0x56780002;
+ wow64_ctx.Dr3 = 0x56780003;
+ wow64_ctx.Dr7 = 0x101; // enable only the first breakpoint
+ ret = pRtlWow64SetThreadContext(pi.hThread, &wow64_ctx);
+ ok(ret == STATUS_SUCCESS, "Wow64SetThreadContext failed with %lx\n", ret);
+
+ ZeroMemory(&wow64_ctx, sizeof(wow64_ctx));
+ wow64_ctx.ContextFlags = WOW64_CONTEXT_ALL;
+ ret = pRtlWow64GetThreadContext(pi.hThread, &wow64_ctx);
+ ok(ret == STATUS_SUCCESS, "Wow64GetThreadContext failed with %lx\n", ret);
+ if (ret == STATUS_SUCCESS)
+ {
+ todo_wine
+ ok(wow64_ctx.Dr0 == 0x56780000, "expected 0x56780000, got %lx\n", wow64_ctx.Dr0);
+ todo_wine
+ ok(wow64_ctx.Dr1 == 0x56780001, "expected 0x56780001, got %lx\n", wow64_ctx.Dr1);
+ todo_wine
+ ok(wow64_ctx.Dr2 == 0x56780002, "expected 0x56780002, got %lx\n", wow64_ctx.Dr2);
+ todo_wine
+ ok(wow64_ctx.Dr3 == 0x56780003, "expected 0x56780003, got %lx\n", wow64_ctx.Dr3);
+ todo_wine
+ ok(wow64_ctx.Dr7 == 0x101, "expected 0x101, got %lx\n", wow64_ctx.Dr7);
+ }
+
+ ZeroMemory(&ctx, sizeof(ctx));
+ ctx.ContextFlags = CONTEXT_ALL;
+ bret = GetThreadContext(pi.hThread, &ctx);
+ todo_wine
+ ok(bret, "GetThreadContext failed\n");
+ if (bret)
+ {
+ ok(ctx.Dr0 == 0x56780000, "expected 0x56780000, got %lx\n", ctx.Dr0);
+ ok(ctx.Dr1 == 0x56780001, "expected 0x56780001, got %lx\n", ctx.Dr1);
+ ok(ctx.Dr2 == 0x56780002, "expected 0x56780002, got %lx\n", ctx.Dr2);
+ ok(ctx.Dr3 == 0x56780003, "expected 0x56780003, got %lx\n", ctx.Dr3);
+ ok(ctx.Dr7 == 0x101, "expected 0x101, got %lx\n", ctx.Dr7);
+ }
+
+ ResumeThread(pi.hThread);
+ TerminateProcess(pi.hProcess, 0);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+}
+
+#endif
+
static DWORD debug_service_exceptions;
static LONG CALLBACK debug_service_handler(EXCEPTION_POINTERS *ExceptionInfo)
@@ -8314,6 +8428,7 @@ START_TEST(exception)
test_rtlraiseexception();
test_debug_registers();
+ test_debug_registers_wow64();
test_debug_service(1);
test_virtual_unwind();
test___C_specific_handler();
--
2.25.1
Feb. 28, 2021
[PATCH v2] po: Update Dutch translation
by Floris Renaud
Signed-off-by: Floris Renaud <jkfloris(a)dds.nl>
---
po/nl.po | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/po/nl.po b/po/nl.po
index d727b541ffa..431693164ce 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -13112,11 +13112,11 @@ msgstr "Wine Verkenner"
#: programs/explorer/explorer.rc:33
msgid "Start"
-msgstr "Opstarten"
+msgstr "Start"
#: programs/explorer/explorer.rc:34 programs/winefile/winefile.rc:36
msgid "&Run..."
-msgstr "&Starten..."
+msgstr "&Uitvoeren..."
#: programs/fsutil/fsutil.mc:28
msgid ""
@@ -16145,10 +16145,10 @@ msgid ""
"linked to the Libraries and Graphics tabs to allow you to change system-wide "
"or per-application settings in those tabs as well."
msgstr ""
-"Wine geeft de mogelijkheid om per toepassing de Windows versie in te "
-"stellen. Dit tabblad is gekoppeld aan de tabbladen 'Bibliotheken' en "
-"'Grafisch' om zowel systeembreed als programmaspecifiek instellingen in deze "
-"tabbladen mogelijk te maken."
+"Voor elk programma kan Wine apart de Windows versie instellen. Dit tabblad is"
+"gekoppeld aan de tabbladen 'Bibliotheken' en 'Grafisch'. Hierdoor kan per "
+"programma de standaardinstellingen of programmaspecifieke instellingen "
+"gebruikt worden."
#: programs/winecfg/winecfg.rc:158
msgid "Add appli&cation..."
@@ -16180,7 +16180,7 @@ msgstr "Laat de vensterbeheerder de vensters &beheren"
#: programs/winecfg/winecfg.rc:172
msgid "&Emulate a virtual desktop"
-msgstr "&Emuleer een virtueel bureaublad"
+msgstr "Maak een &virtueel bureaublad"
#: programs/winecfg/winecfg.rc:174
msgid "Desktop &size:"
@@ -16514,7 +16514,7 @@ msgstr "Automatisch"
#: programs/winecfg/winecfg.rc:69
msgid "Local hard disk"
-msgstr "Hardeschijf"
+msgstr "Harde schijf"
#: programs/winecfg/winecfg.rc:70
msgid "Network share"
@@ -16526,7 +16526,7 @@ msgstr "Diskettestation"
#: programs/winecfg/winecfg.rc:72
msgid "CD-ROM"
-msgstr "Cd-rom"
+msgstr "CD-ROM"
#: programs/winecfg/winecfg.rc:73
msgid ""
@@ -16536,7 +16536,7 @@ msgid ""
msgstr ""
"U kunt geen schijven meer toevoegen.\n"
"\n"
-"Elke schijf moet een letter van A tot Z hebben dus het kunnen er niet meer "
+"Elke schijf moet een letter van A tot Z hebben. Het kunnen er dus niet meer "
"dan 26 zijn."
#: programs/winecfg/winecfg.rc:74
@@ -16727,8 +16727,8 @@ msgid ""
"Database</a> for tips about running this application."
msgstr ""
"Dit kan veroorzaakt worden door een probleem in het programma of een fout in "
-"Wine. U kunt zoeken op <a href=\"https://appdb.winehq.org\">Application "
-"Database</a> naar tips voor dit programma."
+"Wine. Zoek in de <a href=\"https://appdb.winehq.org\">Programma Database</a> "
+"naar tips voor dit programma."
#: programs/winedbg/winedbg.rc:62
msgid "Show &Details"
@@ -16745,9 +16745,9 @@ msgid ""
"button, then <a href=\"https://wiki.winehq.org/Bugs\">file a bug report</a> "
"and attach that file to the report."
msgstr ""
-"Indien dit probleem zich niet voordoet onder Windows en het probleem is nog "
-"niet gerapporteerd, dan kunt U gedetailleerde informatie in een bestand "
-"opslaan met de \"Opslaan als\" knop. Dit bestand kunt U via <a href="
+"Indien dit probleem zich niet voordoet onder Windows en het probleem nog "
+"niet is gerapporteerd, dan kunt u gedetailleerde informatie in een bestand "
+"opslaan met de \"Opslaan als\" knop. Dit bestand kunt u via <a href="
"\"https://wiki.winehq.org/Bugs\">file a bug report</a> versturen."
#: programs/winedbg/winedbg.rc:40
--
2.30.1
Feb. 28, 2021
[PATCH] shell32: Resize Run program window
by Floris Renaud
Three lines of text will now fit in the window. More translations will fit.
Signed-off-by: Floris Renaud <jkfloris(a)dds.nl>
---
dlls/shell32/shell32.rc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc
index f19b09f8c21..ff859381593 100644
--- a/dlls/shell32/shell32.rc
+++ b/dlls/shell32/shell32.rc
@@ -334,7 +334,7 @@ CAPTION "Run"
FONT 8, "MS Shell Dlg"
{
ICON "", IDC_RUNDLG_ICON, 7, 11, 18, 20, WS_VISIBLE
- LTEXT "Type the name of a program, folder, document, or Internet resource, and Wine will open it for you.", IDC_RUNDLG_DESCRIPTION, 36, 11, 182, 18
+ LTEXT "Type the name of a program, folder, document, or Internet resource, and Wine will open it for you.", IDC_RUNDLG_DESCRIPTION, 45, 8, 194, 28
LTEXT "&Open:", IDC_RUNDLG_LABEL, 7, 39, 35, 10
CONTROL "", IDC_RUNDLG_EDITPATH, "COMBOBOX", WS_TABSTOP | WS_GROUP | WS_VSCROLL | WS_VISIBLE | CBS_DISABLENOSCROLL | CBS_AUTOHSCROLL | CBS_DROPDOWN, 45, 37, 185, 100
DEFPUSHBUTTON "OK", IDOK, 72, 63, 50, 14, WS_TABSTOP
--
2.30.1
Feb. 28, 2021
[PATCH] mscoree: Add an option to enable the interpreter.
by Esme Povirk
Signed-off-by: Esme Povirk <esme(a)codeweavers.com>
---
dlls/mscoree/metahost.c | 28 ++++++++++++++++++++++++++++
dlls/mscoree/mscoree_private.h | 12 ++++++++++++
2 files changed, 40 insertions(+)
diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c
index d9b599fadc7..907d8af9791 100644
--- a/dlls/mscoree/metahost.c
+++ b/dlls/mscoree/metahost.c
@@ -106,6 +106,7 @@ MonoImage* (CDECL *mono_image_open_from_module_handle)(HMODULE module_handle, ch
static void (CDECL *mono_install_assembly_preload_hook)(MonoAssemblyPreLoadFunc func, void *user_data);
int (CDECL *mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
MonoDomain* (CDECL *mono_jit_init_version)(const char *domain_name, const char *runtime_version);
+static void (CDECL *mono_jit_set_aot_mode)(MonoAotMode mode);
static int (CDECL *mono_jit_set_trace_options)(const char* options);
void* (CDECL *mono_marshal_get_vtfixup_ftnptr)(MonoImage *image, DWORD token, WORD type);
MonoDomain* (CDECL *mono_object_get_domain)(MonoObject *obj);
@@ -158,6 +159,8 @@ static HRESULT load_mono(LPCWSTR mono_path)
WCHAR mono_dll_path[MAX_PATH+16];
WCHAR mono_lib_path[MAX_PATH+4], mono_etc_path[MAX_PATH+4];
char mono_lib_path_a[MAX_PATH], mono_etc_path_a[MAX_PATH];
+ int aot_size;
+ char aot_setting[256];
int trace_size;
char trace_setting[256];
int verbose_size;
@@ -239,6 +242,7 @@ static HRESULT load_mono(LPCWSTR mono_path)
LOAD_OPT_MONO_FUNCTION(mono_callspec_set_assembly, NULL);
LOAD_OPT_MONO_FUNCTION(mono_image_open_from_module_handle, image_open_module_handle_dummy);
+ LOAD_OPT_MONO_FUNCTION(mono_jit_set_aot_mode, NULL);
LOAD_OPT_MONO_FUNCTION(mono_profiler_create, NULL);
LOAD_OPT_MONO_FUNCTION(mono_profiler_install, NULL);
LOAD_OPT_MONO_FUNCTION(mono_profiler_set_runtime_shutdown_begin_callback, NULL);
@@ -277,6 +281,30 @@ static HRESULT load_mono(LPCWSTR mono_path)
mono_install_assembly_preload_hook(mono_assembly_preload_hook_fn, NULL);
+ aot_size = GetEnvironmentVariableA("WINE_MONO_AOT", aot_setting, sizeof(aot_setting));
+
+ if (aot_size)
+ {
+ MonoAotMode mode;
+ if (strcmp(aot_setting, "interp") == 0)
+ mode = MONO_AOT_MODE_INTERP_ONLY;
+ else if (strcmp(aot_setting, "none") == 0)
+ mode = MONO_AOT_MODE_NONE;
+ else
+ {
+ ERR("unknown WINE_MONO_AOT setting, valid settings are interp and none\n");
+ mode = MONO_AOT_MODE_NONE;
+ }
+ if (mono_jit_set_aot_mode != NULL)
+ {
+ mono_jit_set_aot_mode(mode);
+ }
+ else
+ {
+ ERR("mono_jit_set_aot_mode export not found\n");
+ }
+ }
+
trace_size = GetEnvironmentVariableA("WINE_MONO_TRACE", trace_setting, sizeof(trace_setting));
if (trace_size)
diff --git a/dlls/mscoree/mscoree_private.h b/dlls/mscoree/mscoree_private.h
index da587285cfe..69c30e5e3e0 100644
--- a/dlls/mscoree/mscoree_private.h
+++ b/dlls/mscoree/mscoree_private.h
@@ -147,6 +147,18 @@ typedef void (CDECL *MonoProfileFunc)(MonoProfiler *prof);
typedef void (CDECL *MonoPrintCallback) (const char *string, INT is_stdout);
+typedef enum {
+ MONO_AOT_MODE_NONE,
+ MONO_AOT_MODE_NORMAL,
+ MONO_AOT_MODE_HYBRID,
+ MONO_AOT_MODE_FULL,
+ MONO_AOT_MODE_LLVMONLY,
+ MONO_AOT_MODE_INTERP,
+ MONO_AOT_MODE_INTERP_LLVMONLY,
+ MONO_AOT_MODE_LLVMONLY_INTERP,
+ MONO_AOT_MODE_INTERP_ONLY
+} MonoAotMode;
+
extern BOOL is_mono_started DECLSPEC_HIDDEN;
extern MonoImage* (CDECL *mono_assembly_get_image)(MonoAssembly *assembly) DECLSPEC_HIDDEN;
--
2.25.1
Feb. 28, 2021
[PATCH v2 5/5] aclui: Implement EditSecurity().
by Zebediah Figura
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Zebediah Figura <z.figura12(a)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)
--
2.30.1
Feb. 28, 2021
[PATCH v2 4/5] aclui: Populate the access list.
by Zebediah Figura
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Zebediah Figura <z.figura12(a)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;
}
--
2.30.1
Feb. 28, 2021
[PATCH v2 3/5] aclui: Add icons to the users list.
by Zebediah Figura
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Zebediah Figura <z.figura12(a)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)A>?UD(a)ut;exz8p2V*`?1=8)iGhP3WM|43gK1tH7D
z8bj?`$*&atY)>N!!&Z{9b}ngd2BZl8)|L9C$rjUnv2_eX;$7(MM3$P2bJ7mhChsOT
z=mS(TbJRY(a)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(a)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(a)+-+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(a)FOC&P7(a)28+aFtWvkLJg<#;+v=Dm%fvdWfT$xqC~CTh
zsO#p&_rK`mNc+_(a)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_(a)XEBjn5*@hns%GvET}BmA!Z#9AHgFKeh$kEX!@<+acZi{UEQs
mZ-|`3t(<G``Nvrv<n3+g$E*Ar9%a|qcJ$w2KFI$MfBy-k(a)DaHH
literal 0
HcmV?d00001
--
2.30.1
Feb. 28, 2021
[PATCH v2 2/5] aclui: Populate the users list.
by Zebediah Figura
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Zebediah Figura <z.figura12(a)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
Feb. 28, 2021
[PATCH v2 1/5] aclui: Add an empty ACE editor dialog.
by Zebediah Figura
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Zebediah Figura <z.figura12(a)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__ */
--
2.30.1
Feb. 28, 2021