Rebase against 7d26649f6375cd8bf765405237c85933c58e8de8.

This commit is contained in:
Alistair Leslie-Hughes
2025-09-16 08:32:28 +10:00
parent 978b387c1c
commit 74477d5d72
5 changed files with 1 additions and 231 deletions

View File

@@ -1,137 +0,0 @@
From 03ed95b629a5d5a9b1a8203e08d7db4ce1ed80d9 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 28 Apr 2016 18:14:36 +0800
Subject: [PATCH] ntdll: Implement NtSetLdtEntries.
---
dlls/kernel32/tests/thread.c | 79 +++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/signal_i386.c | 2 +-
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c
index c0303b471e8..9025d66fba6 100644
--- a/dlls/kernel32/tests/thread.c
+++ b/dlls/kernel32/tests/thread.c
@@ -103,6 +103,7 @@ static HRESULT (WINAPI *pSetThreadDescription)(HANDLE,const WCHAR *);
static HRESULT (WINAPI *pGetThreadDescription)(HANDLE,WCHAR **);
static PVOID (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG,PVECTORED_EXCEPTION_HANDLER);
static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID);
+static NTSTATUS (WINAPI *pNtSetLdtEntries)(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
static HANDLE create_target_process(const char *arg)
{
@@ -1319,6 +1320,82 @@ static void test_GetThreadSelectorEntry(void)
ok(entry.HighWord.Bits.Granularity == 1, "expected 1, got %u\n", entry.HighWord.Bits.Granularity);
}
+static void test_NtSetLdtEntries(void)
+{
+ THREAD_DESCRIPTOR_INFORMATION tdi;
+ LDT_ENTRY ds_entry;
+ CONTEXT ctx;
+ DWORD ret;
+ union
+ {
+ LDT_ENTRY entry;
+ DWORD dw[2];
+ } sel;
+
+ if (!pNtSetLdtEntries)
+ {
+ win_skip("NtSetLdtEntries is not available on this platform\n");
+ return;
+ }
+
+ if (pNtSetLdtEntries(0, 0, 0, 0, 0, 0) == STATUS_NOT_IMPLEMENTED) /* WoW64 */
+ {
+ win_skip("NtSetLdtEntries is not implemented on this platform\n");
+ return;
+ }
+
+ ret = pNtSetLdtEntries(0, 0, 0, 0, 0, 0);
+ ok(!ret, "NtSetLdtEntries failed: %08x\n", ret);
+
+ ctx.ContextFlags = CONTEXT_SEGMENTS;
+ ret = GetThreadContext(GetCurrentThread(), &ctx);
+ ok(ret, "GetThreadContext failed\n");
+
+ tdi.Selector = ctx.SegDs;
+ ret = pNtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret);
+ ok(!ret, "NtQueryInformationThread failed: %08x\n", ret);
+ ds_entry = tdi.Entry;
+
+ tdi.Selector = 0x000f;
+ ret = pNtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret);
+ ok(ret == STATUS_ACCESS_VIOLATION, "got %08x\n", ret);
+
+ tdi.Selector = 0x001f;
+ ret = pNtQueryInformationThread(GetCurrentThread(), ThreadDescriptorTableEntry, &tdi, sizeof(tdi), &ret);
+ ok(ret == STATUS_ACCESS_VIOLATION, "NtQueryInformationThread returned %08x\n", ret);
+
+ ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry);
+ ok(!ret, "GetThreadSelectorEntry should fail\n");
+
+ ret = GetThreadSelectorEntry(GetCurrentThread(), 0x001f, &sel.entry);
+ ok(!ret, "GetThreadSelectorEntry should fail\n");
+
+ memset(&sel.entry, 0x9a, sizeof(sel.entry));
+ ret = GetThreadSelectorEntry(GetCurrentThread(), ctx.SegDs, &sel.entry);
+ ok(ret, "GetThreadSelectorEntry failed\n");
+ ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
+
+ ret = pNtSetLdtEntries(0x000f, sel.dw[0], sel.dw[1], 0x001f, sel.dw[0], sel.dw[1]);
+ ok(!ret || broken(ret == STATUS_INVALID_LDT_DESCRIPTOR) /*XP*/, "NtSetLdtEntries failed: %08x\n", ret);
+
+ if (!ret)
+ {
+ memset(&sel.entry, 0x9a, sizeof(sel.entry));
+ ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry);
+ todo_wine
+ ok(ret, "GetThreadSelectorEntry failed\n");
+ todo_wine
+ ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
+
+ memset(&sel.entry, 0x9a, sizeof(sel.entry));
+ ret = GetThreadSelectorEntry(GetCurrentThread(), 0x001f, &sel.entry);
+ todo_wine
+ ok(ret, "GetThreadSelectorEntry failed\n");
+ todo_wine
+ ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
+ }
+}
+
#endif /* __i386__ */
static HANDLE finish_event;
@@ -2644,6 +2721,7 @@ static void init_funcs(void)
X(NtSetInformationThread);
X(RtlAddVectoredExceptionHandler);
X(RtlRemoveVectoredExceptionHandler);
+ X(NtSetLdtEntries);
}
#undef X
}
@@ -2700,6 +2778,7 @@ START_TEST(thread)
test_SetThreadContext();
test_GetThreadSelectorEntry();
test_GetThreadContext();
+ test_NtSetLdtEntries();
#endif
test_QueueUserWorkItem();
test_RegisterWaitForSingleObject();
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 670a3c25015..b4a2392630f 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -2271,7 +2271,7 @@ NTSTATUS get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_
if (reply->flags)
info->Entry = ldt_make_entry( reply->base, reply->limit, reply->flags );
else
- status = STATUS_UNSUCCESSFUL;
+ status = STATUS_ACCESS_VIOLATION;
}
}
SERVER_END_REQ;
--
2.50.1

View File

@@ -1,59 +0,0 @@
From 13b77a54bad4d9b390d2e31f70d8f130eab48635 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 28 Apr 2016 17:01:16 +0200
Subject: [PATCH] libs/wine: Allow to modify reserved LDT entries.
Some implementation notes:
1. Some copy protections call NtSetLdtEntries(0x000f) and then with 'retf'
instruction jump to that selector expecting that it works (the tests show that
NtSetLdtEntries(0x000f,0x001f) should succeed). In order to make this work a
limitation to set only selectors > LDT_FIRST_ENTRY (512) in wine_ldt_set_entry()
was removed.
2. wine_ldt_set_entry() was made to always mark modified selector entries as
WINE_LDT_FLAGS_ALLOCATED, otherwise get_selector_entry() server call returns
entries without that flag set and NtQueryInformationThread(ThreadDescriptorTableEntry)
fails.
---
dlls/kernel32/tests/thread.c | 4 ----
dlls/ntdll/unix/signal_i386.c | 2 --
3 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c
index a76d74cb698..881db6d6513 100644
--- a/dlls/kernel32/tests/thread.c
+++ b/dlls/kernel32/tests/thread.c
@@ -1341,16 +1341,12 @@ static void test_NtSetLdtEntries(void)
{
memset(&sel.entry, 0x9a, sizeof(sel.entry));
ret = GetThreadSelectorEntry(GetCurrentThread(), 0x000f, &sel.entry);
- todo_wine
ok(ret, "GetThreadSelectorEntry failed\n");
- todo_wine
ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
memset(&sel.entry, 0x9a, sizeof(sel.entry));
ret = GetThreadSelectorEntry(GetCurrentThread(), 0x001f, &sel.entry);
- todo_wine
ok(ret, "GetThreadSelectorEntry failed\n");
- todo_wine
ok(!memcmp(&ds_entry, &sel.entry, sizeof(ds_entry)), "entries do not match\n");
}
}
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 30f1aee4d62..0ab09c1b4df 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -2098,8 +2098,6 @@ NTSTATUS WINAPI NtSetLdtEntries( ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_E
sigset_t sigset;
if (sel1 >> 16 || sel2 >> 16) return STATUS_INVALID_LDT_DESCRIPTOR;
- if (sel1 && (sel1 >> 3) < first_ldt_entry) return STATUS_INVALID_LDT_DESCRIPTOR;
- if (sel2 && (sel2 >> 3) < first_ldt_entry) return STATUS_INVALID_LDT_DESCRIPTOR;
server_enter_uninterrupted_section( &ldt_mutex, &sigset );
if (sel1) ldt_set_entry( sel1, entry1 );
--
2.27.0

View File

@@ -1,33 +0,0 @@
From 376bc1c96b3fe8aa79516198aa59763a762392ee Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 27 Sep 2015 19:35:05 +0200
Subject: user32: Refresh MDI menus when DefMDIChildProc(WM_SETTEXT) is
called.
---
dlls/user32/mdi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dlls/user32/mdi.c b/dlls/user32/mdi.c
index 41b5077..635c8b2 100644
--- a/dlls/user32/mdi.c
+++ b/dlls/user32/mdi.c
@@ -1425,6 +1425,7 @@ LRESULT WINAPI DefMDIChildProcA( HWND hwnd, UINT message,
DefWindowProcA(hwnd, message, wParam, lParam);
if( ci->hwndChildMaximized == hwnd )
MDI_UpdateFrameText( GetParent(client), client, TRUE, NULL );
+ MDI_RefreshMenu( ci );
return 1; /* success. FIXME: check text length */
case WM_GETMINMAXINFO:
@@ -1465,6 +1466,7 @@ LRESULT WINAPI DefMDIChildProcW( HWND hwnd, UINT message,
DefWindowProcW(hwnd, message, wParam, lParam);
if( ci->hwndChildMaximized == hwnd )
MDI_UpdateFrameText( GetParent(client), client, TRUE, NULL );
+ MDI_RefreshMenu( ci );
return 1; /* success. FIXME: check text length */
case WM_GETMINMAXINFO:
--
2.5.1

View File

@@ -1 +0,0 @@
Fixes: [21855] Refresh MDI menus when DefMDIChildProc(WM_SETTEXT) is called

View File

@@ -1 +1 @@
72dc2afb1a78f88cd930d61a20498838a3bea271
7d26649f6375cd8bf765405237c85933c58e8de8