Rebase against 262e4ab9e0eeb126dde5cb4cba13fbf7f1d1cef0.

This commit is contained in:
Zebediah Figura 2020-07-08 20:46:51 -05:00
parent 553c1cff5a
commit f6954e6e77
19 changed files with 164 additions and 2260 deletions

View File

@ -1,4 +1,4 @@
From 67cacb66b16c354aa30f4c94bba9da44f7e45619 Mon Sep 17 00:00:00 2001
From 3473ccddec5c67bbfe1d477ce36f537493fae54b Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:02:11 -0700
Subject: [PATCH] kernel32,ntdll: Add support for deleting junction points with
@ -6,55 +6,14 @@ Subject: [PATCH] kernel32,ntdll: Add support for deleting junction points with
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
dlls/kernel32/path.c | 19 +++++++++++++------
dlls/ntdll/tests/file.c | 34 +++++++++++++++++++++++++++++++++-
2 files changed, 46 insertions(+), 7 deletions(-)
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index db2c1fb0240..6b7912359cf 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -233,6 +233,7 @@ BOOL WINAPI CreateDirectoryExA( LPCSTR template, LPCSTR path, LPSECURITY_ATTRIBU
*/
BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
{
+ FILE_BASIC_INFORMATION info;
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nt_name;
ANSI_STRING unix_name;
@@ -264,15 +265,21 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
}
status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN );
- RtlFreeUnicodeString( &nt_name );
- if (!set_ntstatus( status ))
+ if (status == STATUS_SUCCESS)
{
- NtClose( handle );
- return FALSE;
+ status = NtQueryAttributesFile( &attr, &info );
+ if (status == STATUS_SUCCESS && (info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ ret = (unlink( unix_name.Buffer ) != -1);
+ else
+ ret = (rmdir( unix_name.Buffer ) != -1);
+ if (!ret) FILE_SetDosError();
+ RtlFreeAnsiString( &unix_name );
}
+ else
+ set_ntstatus( status );
+ RtlFreeUnicodeString( &nt_name );
- if (!(ret = (rmdir( unix_name.Buffer ) != -1))) FILE_SetDosError();
- RtlFreeAnsiString( &unix_name );
NtClose( handle );
return ret;
}
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index c7107500939..5b71f6f658b 100644
index 6b3071f4095..1d5e0ce95b0 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5009,7 +5009,7 @@ static void test_reparse_points(void)
@@ -5010,7 +5010,7 @@ static void test_reparse_points(void)
REPARSE_GUID_DATA_BUFFER guid_buffer;
static const WCHAR dotW[] = {'.',0};
REPARSE_DATA_BUFFER *buffer = NULL;
@ -63,7 +22,7 @@ index c7107500939..5b71f6f658b 100644
INT buffer_len, string_len;
IO_STATUS_BLOCK iosb;
UNICODE_STRING nameW;
@@ -5098,6 +5098,38 @@ static void test_reparse_points(void)
@@ -5099,6 +5099,38 @@ static void test_reparse_points(void)
"Junction point folder's access time does not match.\n");
CloseHandle(handle);

View File

@ -1,48 +0,0 @@
From 95288f8fe17bf7c8f772c863fe49a85c117a71eb Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Sat, 30 Mar 2019 12:01:50 -0600
Subject: kernel32: Set error code when attempting to delete file symlinks as
directories.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
dlls/kernel32/path.c | 5 ++++-
dlls/ntdll/tests/file.c | 6 +++---
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index 5ef66b5913..227473f71a 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -1738,7 +1738,10 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
ret = (unlink( unix_name.Buffer ) != -1);
else
ret = (rmdir( unix_name.Buffer ) != -1);
- if (!ret) FILE_SetDosError();
+ if (status == STATUS_SUCCESS && (info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ !(info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ SetLastError( ERROR_DIRECTORY );
+ else if (!ret) FILE_SetDosError();
RtlFreeAnsiString( &unix_name );
}
else
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index fbd824fd10..0041a41b6d 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5067,9 +5067,9 @@ static void test_reparse_points(void)
bret = RemoveDirectoryW(reparse_path);
ok(!bret, "Succeeded in deleting file symlink as a directory!\n");
err = GetLastError();
- todo_wine ok(err == ERROR_DIRECTORY,
- "Expected last error 0x%x for RemoveDirectory on file symlink (actually 0x%x)!\n",
- ERROR_DIRECTORY, err);
+ ok(err == ERROR_DIRECTORY,
+ "Expected last error 0x%x for RemoveDirectory on file symlink (actually 0x%x)!\n",
+ ERROR_DIRECTORY, err);
dwret = GetFileAttributesW(reparse_path);
ok(dwret != (DWORD)~0, "Symlink doesn't exist (attributes: 0x%x)!\n", dwret);
ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a symlink! (attributes: 0x%x)\n", dwret);
--
2.17.1

View File

@ -2,4 +2,5 @@ Fixes: [12401] NET Framework 2.0, 3.0, 4.0 installers and other apps that make u
Fixes: [44948] Multiple apps (Spine (Mod starter for Gothic), MS Office 365 installer) need CreateSymbolicLinkW implementation
# FIXME: patch 0006 was broken by e36a9c459d. We really want to get that information from ntdll instead, but the how is not trivial...
# FIXME 2: patch 0019 needs to call RemoveDirectoryW() from kernelbase, but it's stuck in kernel32 for now...
# FIXME 3: RemoveDirectory() doesn't work anymore, I think.
Depends: ntdll-DOS_Attributes

View File

@ -1,4 +1,3 @@
Fixes: [48291] Detroit: Become Human crashes on launch
Depends: winebuild-Fake_Dlls
# Re-enable me when winebuild-Fake_Dlls gets re-enabled!
# Needs to be reimplemented on top of upstream syscall changes.
Disabled: true

View File

@ -1,92 +0,0 @@
From 11ce8824189ece2741a98c932b22ac7ccf2f4388 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 9 Mar 2017 00:00:46 +0100
Subject: [PATCH] ntdll: Set correct thread creation time for
SystemProcessInformation in NtQuerySystemInformation.
---
dlls/ntdll/unix/system.c | 4 +++-
server/protocol.def | 1 +
server/snapshot.c | 13 +++++++------
server/thread.h | 1 +
4 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index 7045bc1550b..3d37578b34a 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -2162,6 +2162,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
while (ret == STATUS_SUCCESS)
{
int unix_tid, pid, tid, base_pri, delta_pri;
+ timeout_t creation_time;
SERVER_START_REQ( next_thread )
{
req->handle = wine_server_obj_handle( handle );
@@ -2173,6 +2174,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
tid = reply->tid;
base_pri = reply->base_pri;
delta_pri = reply->delta_pri;
+ creation_time = reply->creation_time;
j++;
}
}
@@ -2184,7 +2186,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
{
memset(&spi->ti[i], 0, sizeof(spi->ti));
- spi->ti[i].CreateTime.QuadPart = 0xdeadbeef;
+ spi->ti[i].CreateTime.QuadPart = creation_time;
spi->ti[i].ClientId.UniqueProcess = UlongToHandle(pid);
spi->ti[i].ClientId.UniqueThread = UlongToHandle(tid);
spi->ti[i].dwCurrentPriority = base_pri + delta_pri;
diff --git a/server/protocol.def b/server/protocol.def
index 38079f23daf..89a0332691c 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1911,6 +1911,7 @@ enum char_info_mode
int count; /* thread usage count */
process_id_t pid; /* process id */
thread_id_t tid; /* thread id */
+ timeout_t creation_time; /* thread creation time */
int base_pri; /* base priority */
int delta_pri; /* delta priority */
int unix_tid; /* thread native pid */
diff --git a/server/snapshot.c b/server/snapshot.c
index bdceaef5302..fe25e07e02a 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -145,12 +145,13 @@ static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_r
return 0;
}
ptr = &snapshot->threads[snapshot->thread_pos++];
- reply->count = ptr->count;
- reply->pid = get_process_id( ptr->thread->process );
- reply->tid = get_thread_id( ptr->thread );
- reply->base_pri = ptr->priority;
- reply->delta_pri = 0; /* FIXME */
- reply->unix_tid = ptr->thread->unix_tid;
+ reply->count = ptr->count;
+ reply->pid = get_process_id( ptr->thread->process );
+ reply->tid = get_thread_id( ptr->thread );
+ reply->creation_time = get_thread_creation_time( ptr->thread );
+ reply->base_pri = ptr->priority;
+ reply->delta_pri = 0; /* FIXME */
+ reply->unix_tid = ptr->thread->unix_tid;
return 1;
}
diff --git a/server/thread.h b/server/thread.h
index 5d12d24dd89..43b17534693 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -150,5 +150,6 @@ static inline void clear_error(void) { set_error(0); }
static inline void set_win32_error( unsigned int err ) { set_error( 0xc0010000 | err ); }
static inline thread_id_t get_thread_id( struct thread *thread ) { return thread->id; }
+static inline timeout_t get_thread_creation_time( struct thread *thread ) { return thread->creation_time; }
#endif /* __WINE_SERVER_THREAD_H */
--
2.27.0

View File

@ -1,64 +0,0 @@
From 72c4b3f95ad4c8a8ed31ad61c3678cf7d534fba9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 9 Mar 2017 16:32:59 +0100
Subject: [PATCH] ntdll: Set process start time.
---
dlls/ntdll/unix/system.c | 1 +
server/protocol.def | 1 +
server/snapshot.c | 15 ++++++++-------
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index f137ccf97a7..94915bd9e47 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -2137,6 +2137,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
spi->UniqueProcessId = UlongToHandle(reply->pid);
spi->ParentProcessId = UlongToHandle(reply->ppid);
spi->HandleCount = reply->handles;
+ spi->CreationTime.QuadPart = reply->start_time;
/* spi->ti will be set later on */
diff --git a/server/protocol.def b/server/protocol.def
index 89a0332691c..b29e014958e 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1899,6 +1899,7 @@ enum char_info_mode
int priority; /* process priority */
int handles; /* number of handles */
int unix_pid; /* Unix pid */
+ timeout_t start_time; /* start time */
VARARG(filename,unicode_str); /* file name of main exe */
@END
diff --git a/server/snapshot.c b/server/snapshot.c
index fe25e07e02a..b6b790e21bd 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -114,13 +114,14 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process
return 0;
}
ptr = &snapshot->processes[snapshot->process_pos++];
- reply->count = ptr->count;
- reply->pid = get_process_id( ptr->process );
- reply->ppid = ptr->process->parent_id;
- reply->threads = ptr->threads;
- reply->priority = ptr->priority;
- reply->handles = ptr->handles;
- reply->unix_pid = ptr->process->unix_pid;
+ reply->count = ptr->count;
+ reply->pid = get_process_id( ptr->process );
+ reply->ppid = ptr->process->parent_id;
+ reply->threads = ptr->threads;
+ reply->priority = ptr->priority;
+ reply->handles = ptr->handles;
+ reply->unix_pid = ptr->process->unix_pid;
+ reply->start_time = ptr->process->start_time;
if ((exe_module = get_process_exe_module( ptr->process )) && exe_module->filename)
{
data_size_t len = min( exe_module->namelen, get_reply_max_size() );
--
2.27.0

View File

@ -1,4 +1,3 @@
Fixes: Use a separate stack when starting new threads
Fixes: Ignore invalid exit_frame when exiting thread
Depends: ntdll-ThreadTime
Disabled: true

View File

@ -52,7 +52,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "e0e3b6bc91f7db956e3a66f2938eea45d4055a39"
echo "262e4ab9e0eeb126dde5cb4cba13fbf7f1d1cef0"
}
# Show version information
@ -3669,8 +3669,9 @@ fi
# | * [#44948] Multiple apps (Spine (Mod starter for Gothic), MS Office 365 installer) need CreateSymbolicLinkW implementation
# |
# | Modified files:
# | * configure.ac, dlls/kernel32/path.c, dlls/ntdll/tests/file.c, dlls/ntdll/unix/file.c, include/Makefile.in,
# | include/ntifs.h, include/wine/port.h, include/winternl.h, libs/port/Makefile.in, libs/port/renameat2.c, server/fd.c
# | * configure.ac, dlls/kernel32/path.c, dlls/kernel32/tests/path.c, dlls/kernelbase/file.c, dlls/msvcp120/tests/msvcp120.c,
# | dlls/msvcp140/tests/msvcp140.c, dlls/ntdll/tests/file.c, dlls/ntdll/unix/file.c, include/Makefile.in, include/ntifs.h,
# | include/wine/port.h, include/winternl.h, libs/port/Makefile.in, libs/port/renameat2.c, server/fd.c
# |
if test "$enable_ntdll_Junction_Points" -eq 1; then
patch_apply ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch
@ -3686,10 +3687,10 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then
patch_apply ntdll-Junction_Points/0012-ntdll-Add-support-for-file-symlinks.patch
patch_apply ntdll-Junction_Points/0013-ntdll-Allow-creation-of-dangling-reparse-points-to-n.patch
patch_apply ntdll-Junction_Points/0014-ntdll-Correctly-report-file-symbolic-links-as-files.patch
patch_apply ntdll-Junction_Points/0015-kernel32-Set-error-code-when-attempting-to-delete-fi.patch
patch_apply ntdll-Junction_Points/0016-server-Properly-handle-file-symlink-deletion.patch
patch_apply ntdll-Junction_Points/0017-ntdll-Always-report-symbolic-links-as-containing-zer.patch
patch_apply ntdll-Junction_Points/0018-ntdll-Find-dangling-symlinks-quickly.patch
patch_apply ntdll-Junction_Points/0019-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch
(
printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for junction point creation.", 1 },';
printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for reading junction points.", 1 },';
@ -3704,10 +3705,10 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then
printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for file symlinks.", 1 },';
printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Allow creation of dangling reparse points to non-existent paths.", 1 },';
printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Correctly report file symbolic links as files.", 1 },';
printf '%s\n' '+ { "Erich E. Hoover", "kernel32: Set error code when attempting to delete file symlinks as directories.", 1 },';
printf '%s\n' '+ { "Erich E. Hoover", "server: Properly handle file symlink deletion.", 1 },';
printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Always report symbolic links as containing zero bytes.", 1 },';
printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Find dangling symlinks quickly.", 1 },';
printf '%s\n' '+ { "Erich E. Hoover", "kernel32: Implement CreateSymbolicLink[A|W] with ntdll reparse points.", 1 },';
) >> "$patchlist"
fi
@ -4470,7 +4471,7 @@ fi
# | * [#45374] Yet Another Process Monitor (.NET 2.0 app) reports System.AccessViolationException
# |
# | Modified files:
# | * dlls/ntdll/om.c, dlls/ntdll/tests/info.c, dlls/ntdll/tests/om.c, dlls/ntdll/unix/system.c, include/winternl.h,
# | * dlls/ntdll/tests/info.c, dlls/ntdll/tests/om.c, dlls/ntdll/unix/file.c, dlls/ntdll/unix/system.c, include/winternl.h,
# | server/completion.c, server/directory.c, server/event.c, server/file.c, server/handle.c, server/mailslot.c,
# | server/main.c, server/mapping.c, server/mutex.c, server/named_pipe.c, server/object.c, server/object.h,
# | server/process.c, server/protocol.def, server/registry.c, server/semaphore.c, server/symlink.c, server/thread.c,

View File

@ -1,90 +1,21 @@
From df0394fbe1b04909081ab265eb8ec7f20ff4e8b6 Mon Sep 17 00:00:00 2001
From 6c4383e0d465d9cf79e772687111ac7b5d250b75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 02:12:37 +0100
Subject: ntdll: Implement ObjectTypesInformation in NtQueryObject.
Subject: [PATCH] ntdll: Implement ObjectTypesInformation in NtQueryObject.
---
dlls/ntdll/om.c | 51 ++++++++++++++++++++++++++++++++++++++
dlls/ntdll/tests/om.c | 57 +++++++++++++++++++++++++++++++++++++++++++
include/winternl.h | 30 +++++++++++++++++++++--
server/directory.c | 19 ++++++++++++++-
server/protocol.def | 9 +++++++
5 files changed, 163 insertions(+), 3 deletions(-)
dlls/ntdll/tests/om.c | 57 ++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/file.c | 53 +++++++++++++++++++++++++++++++++++++++
include/winternl.h | 30 ++++++++++++++++++++--
server/directory.c | 19 +++++++++++++-
server/protocol.def | 9 +++++++
5 files changed, 165 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 0b562513..88a4f800 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -42,6 +42,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
/*
* Generic object functions
@@ -187,6 +188,56 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
SERVER_END_REQ;
}
break;
+ case ObjectTypesInformation:
+ {
+ OBJECT_TYPES_INFORMATION *p = ptr;
+ OBJECT_TYPE_INFORMATION *type = (OBJECT_TYPE_INFORMATION *)(p + 1);
+ ULONG count, type_len, req_len = sizeof(OBJECT_TYPES_INFORMATION);
+
+ for (count = 0, status = STATUS_SUCCESS; !status; count++)
+ {
+ SERVER_START_REQ( get_object_type_by_index )
+ {
+ req->index = count;
+ if (len > sizeof(*type))
+ wine_server_set_reply( req, type + 1, len - sizeof(*type) );
+ status = wine_server_call( req );
+ if (status == STATUS_SUCCESS)
+ {
+ type_len = sizeof(*type);
+ if (reply->total)
+ type_len += ROUND_UP( reply->total + sizeof(WCHAR), sizeof(DWORD_PTR) );
+ req_len += type_len;
+ }
+ if (status == STATUS_SUCCESS && len >= req_len)
+ {
+ ULONG res = wine_server_reply_size( reply );
+ memset( type, 0, sizeof(*type) );
+ if (reply->total)
+ {
+ type->TypeName.Buffer = (WCHAR *)(type + 1);
+ type->TypeName.Length = res;
+ type->TypeName.MaximumLength = res + sizeof(WCHAR);
+ type->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
+ }
+ type->TypeIndex = count;
+ type = (OBJECT_TYPE_INFORMATION *)((char *)type + type_len);
+ }
+ }
+ SERVER_END_REQ;
+ }
+
+ if (status != STATUS_NO_MORE_ENTRIES)
+ return status;
+
+ if (used_len) *used_len = req_len;
+ if (len < req_len)
+ return STATUS_INFO_LENGTH_MISMATCH;
+
+ p->NumberOfTypes = count - 1;
+ status = STATUS_SUCCESS;
+ }
+ break;
case ObjectDataInformation:
{
OBJECT_DATA_INFORMATION* p = ptr;
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 3f627aad..dbe7be39 100644
index c17b6ffa8db..6e760066915 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -79,6 +79,21 @@ static void (WINAPI *pRtlWakeAddressSingle)( const void * );
@@ -81,6 +81,21 @@ static void (WINAPI *pRtlWakeAddressSingle)( const void * );
#define KEYEDEVENT_WAKE 0x0002
#define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
@ -106,7 +37,7 @@ index 3f627aad..dbe7be39 100644
static void test_case_sensitive (void)
{
static const WCHAR buffer1[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0};
@@ -1579,6 +1594,47 @@ static void test_query_object(void)
@@ -1583,6 +1598,47 @@ static void test_query_object(void)
}
@ -154,7 +85,7 @@ index 3f627aad..dbe7be39 100644
static void test_type_mismatch(void)
{
HANDLE h;
@@ -2178,6 +2234,7 @@ START_TEST(om)
@@ -2215,6 +2271,7 @@ START_TEST(om)
test_directory();
test_symboliclink();
test_query_object();
@ -162,11 +93,82 @@ index 3f627aad..dbe7be39 100644
test_type_mismatch();
test_event();
test_mutant();
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index dff246f5e74..708fe842020 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -130,6 +130,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(file);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
+#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
+
#define MAX_DOS_DRIVES 26
#define FILE_WRITE_TO_END_OF_FILE ((LONGLONG)-1)
@@ -6464,6 +6466,57 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
break;
}
+ case ObjectTypesInformation:
+ {
+ OBJECT_TYPES_INFORMATION *p = ptr;
+ OBJECT_TYPE_INFORMATION *type = (OBJECT_TYPE_INFORMATION *)(p + 1);
+ ULONG count, type_len, req_len = sizeof(OBJECT_TYPES_INFORMATION);
+
+ for (count = 0, status = STATUS_SUCCESS; !status; count++)
+ {
+ SERVER_START_REQ( get_object_type_by_index )
+ {
+ req->index = count;
+ if (len > sizeof(*type))
+ wine_server_set_reply( req, type + 1, len - sizeof(*type) );
+ status = wine_server_call( req );
+ if (status == STATUS_SUCCESS)
+ {
+ type_len = sizeof(*type);
+ if (reply->total)
+ type_len += ROUND_UP( reply->total + sizeof(WCHAR), sizeof(DWORD_PTR) );
+ req_len += type_len;
+ }
+ if (status == STATUS_SUCCESS && len >= req_len)
+ {
+ ULONG res = wine_server_reply_size( reply );
+ memset( type, 0, sizeof(*type) );
+ if (reply->total)
+ {
+ type->TypeName.Buffer = (WCHAR *)(type + 1);
+ type->TypeName.Length = res;
+ type->TypeName.MaximumLength = res + sizeof(WCHAR);
+ type->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
+ }
+ type->TypeIndex = count;
+ type = (OBJECT_TYPE_INFORMATION *)((char *)type + type_len);
+ }
+ }
+ SERVER_END_REQ;
+ }
+
+ if (status != STATUS_NO_MORE_ENTRIES)
+ return status;
+
+ if (used_len) *used_len = req_len;
+ if (len < req_len)
+ return STATUS_INFO_LENGTH_MISMATCH;
+
+ p->NumberOfTypes = count - 1;
+ status = STATUS_SUCCESS;
+ break;
+ }
+
case ObjectDataInformation:
{
OBJECT_DATA_INFORMATION* p = ptr;
diff --git a/include/winternl.h b/include/winternl.h
index 0c8a5014..0b17c2f5 100644
index 347b79ef8e0..fbc52b7d127 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -826,7 +826,7 @@ typedef enum _OBJECT_INFORMATION_CLASS {
@@ -843,7 +843,7 @@ typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
@ -175,7 +177,7 @@ index 0c8a5014..0b17c2f5 100644
ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
@@ -1237,9 +1237,35 @@ typedef struct _OBJECT_NAME_INFORMATION {
@@ -1281,9 +1281,35 @@ typedef struct _OBJECT_NAME_INFORMATION {
typedef struct __OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
@ -213,10 +215,10 @@ index 0c8a5014..0b17c2f5 100644
#ifdef __WINESRC__
DWORD_PTR ExitStatus;
diff --git a/server/directory.c b/server/directory.c
index 6aa3a55f..6e22a741 100644
index 4d38393a6c8..799102379ff 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -71,6 +71,8 @@ static const struct object_ops object_type_ops =
@@ -72,6 +72,8 @@ static const struct object_ops object_type_ops =
no_destroy /* destroy */
};
@ -235,7 +237,7 @@ index 6aa3a55f..6e22a741 100644
make_object_static( &type->obj );
}
clear_error();
@@ -529,3 +532,17 @@ DECL_HANDLER(get_object_type)
@@ -563,3 +566,17 @@ DECL_HANDLER(get_object_type)
}
release_object( obj );
}
@ -254,10 +256,10 @@ index 6aa3a55f..6e22a741 100644
+ else set_error( STATUS_NO_MORE_ENTRIES );
+}
diff --git a/server/protocol.def b/server/protocol.def
index 3ffb8940..0d866986 100644
index bf2d8bfd167..def84b35967 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3575,6 +3575,15 @@ struct handle_info
@@ -3533,6 +3533,15 @@ struct handle_info
@END
@ -274,5 +276,5 @@ index 3ffb8940..0d866986 100644
@REQ(unlink_object)
obj_handle_t handle; /* handle to the object */
--
2.20.1
2.27.0

View File

@ -1,31 +1,32 @@
From 1e3e93483b223c6e0e9d712fff4a8874c503c973 Mon Sep 17 00:00:00 2001
From 574a79c56964a86181cb721b5e7e4f672455027e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 17:41:11 +0100
Subject: ntdll: Set TypeIndex for ObjectTypeInformation in NtQueryObject.
Subject: [PATCH] ntdll: Set TypeIndex for ObjectTypeInformation in
NtQueryObject.
---
dlls/ntdll/om.c | 4 ++++
server/directory.c | 5 ++++-
server/protocol.def | 1 +
dlls/ntdll/unix/file.c | 4 ++++
server/directory.c | 5 ++++-
server/protocol.def | 1 +
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 8911a28b20..8f54d4f49f 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -184,6 +184,10 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
p->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
}
+ if (status == STATUS_SUCCESS)
+ {
+ p->TypeIndex = reply->index;
+ }
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 708fe842020..4544df55d16 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -6460,6 +6460,10 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
p->TypeName.Buffer[res / sizeof(WCHAR)] = 0;
if (used_len) *used_len = sizeof(*p) + p->TypeName.MaximumLength;
}
+ if (status == STATUS_SUCCESS)
+ {
+ p->TypeIndex = reply->index;
+ }
}
SERVER_END_REQ;
}
SERVER_END_REQ;
diff --git a/server/directory.c b/server/directory.c
index b4f53e2edf..59c8194d09 100644
index 0d5a320690e..1bc97fb2682 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -44,6 +44,7 @@
@ -36,7 +37,7 @@ index b4f53e2edf..59c8194d09 100644
};
static void object_type_dump( struct object *obj, int verbose );
@@ -239,7 +240,8 @@ struct object_type *get_object_type( const struct unicode_str *name )
@@ -237,7 +238,8 @@ struct object_type *get_object_type( const struct unicode_str *name )
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
assert( object_type_count < sizeof(object_type_list)/sizeof(object_type_list[0]) );
@ -46,7 +47,7 @@ index b4f53e2edf..59c8194d09 100644
make_object_static( &type->obj );
}
clear_error();
@@ -528,6 +530,7 @@ DECL_HANDLER(get_object_type)
@@ -560,6 +562,7 @@ DECL_HANDLER(get_object_type)
{
if ((name = get_object_name( &type->obj, &reply->total )))
set_reply_data( name, min( reply->total, get_reply_max_size() ) );
@ -55,10 +56,10 @@ index b4f53e2edf..59c8194d09 100644
}
release_object( obj );
diff --git a/server/protocol.def b/server/protocol.def
index 98c4c58a4e..d6847f8d55 100644
index def84b35967..3406a056688 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3543,6 +3543,7 @@ struct handle_info
@@ -3528,6 +3528,7 @@ struct handle_info
@REQ(get_object_type)
obj_handle_t handle; /* handle to the object */
@REPLY
@ -67,5 +68,5 @@ index 98c4c58a4e..d6847f8d55 100644
VARARG(type,unicode_str); /* type name */
@END
--
2.11.0
2.27.0

View File

@ -1,31 +1,15 @@
From 76c342fe6c01c59bfcf387f19046d78415227f3d Mon Sep 17 00:00:00 2001
From a82fe5d2ad7ff0683ca7078dffb232676ea8a16f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 8 Mar 2017 19:39:29 +0100
Subject: [PATCH] ntdll: Mimic object type behavior for different windows
versions.
---
dlls/ntdll/om.c | 5 +++-
dlls/ntdll/tests/om.c | 65 +++++++++++++++++++++++++++++++++++++++-
dlls/ntdll/unix/file.c | 5 +++-
dlls/ntdll/unix/system.c | 17 +++++++++--
3 files changed, 82 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c
index 4fea106cc46..eea095acbf9 100644
--- a/dlls/ntdll/om.c
+++ b/dlls/ntdll/om.c
@@ -182,7 +182,10 @@ NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
}
if (status == STATUS_SUCCESS)
{
- p->TypeIndex = reply->index;
+ WORD version = MAKEWORD(NtCurrentTeb()->Peb->OSMinorVersion,
+ NtCurrentTeb()->Peb->OSMajorVersion);
+ if (version >= 0x0602)
+ p->TypeIndex = reply->index;
}
}
}
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 398ad6bed4e..b538160f6d0 100644
--- a/dlls/ntdll/tests/om.c
@ -134,8 +118,24 @@ index 398ad6bed4e..b538160f6d0 100644
test_case_sensitive();
test_namespace_pipe();
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 4544df55d16..8ff963585da 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -6462,7 +6462,10 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas
}
if (status == STATUS_SUCCESS)
{
- p->TypeIndex = reply->index;
+ WORD version = MAKEWORD(NtCurrentTeb()->Peb->OSMinorVersion,
+ NtCurrentTeb()->Peb->OSMajorVersion);
+ if (version >= 0x0602)
+ p->TypeIndex = reply->index;
}
}
}
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index 9b42c475b47..828b891be9c 100644
index cd2f45d9f55..b56747e0273 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -2024,6 +2024,18 @@ static void get_timezone_info( RTL_DYNAMIC_TIME_ZONE_INFORMATION *tzi )
@ -157,7 +157,7 @@ index 9b42c475b47..828b891be9c 100644
/******************************************************************************
* NtQuerySystemInformation (NTDLL.@)
@@ -2407,7 +2419,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
@@ -2390,7 +2402,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
shi->Handle[i].OwnerPid = handle_info[i].owner;
shi->Handle[i].HandleValue = handle_info[i].handle;
shi->Handle[i].AccessMask = handle_info[i].access;
@ -166,7 +166,7 @@ index 9b42c475b47..828b891be9c 100644
/* FIXME: Fill out HandleFlags, ObjectPointer */
}
}
@@ -2460,7 +2472,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
@@ -2443,7 +2455,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
shi->Handle[i].UniqueProcessId = handle_info[i].owner;
shi->Handle[i].HandleValue = handle_info[i].handle;
shi->Handle[i].GrantedAccess = handle_info[i].access;
@ -175,7 +175,7 @@ index 9b42c475b47..828b891be9c 100644
/* FIXME: Fill out remaining fields */
}
}
@@ -2720,7 +2732,6 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
@@ -2663,7 +2675,6 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
return ret;
}

View File

@ -1,121 +0,0 @@
From 8b88aa45856684e63786425f72886f2ac57b3630 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 25 May 2017 07:02:46 +0200
Subject: [PATCH] kernel32/tests: Add basic tests for fake dlls.
---
dlls/kernel32/tests/loader.c | 91 ++++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index ef8c47c04f1a..efd5a25a432d 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -1572,6 +1572,96 @@ static void test_filenames(void)
DeleteFileA( long_path );
}
+static void test_FakeDLL(void)
+{
+#ifdef __i386__
+ NTSTATUS (WINAPI *pNtSetEvent)(HANDLE, ULONG *) = NULL;
+ IMAGE_EXPORT_DIRECTORY *dir;
+ HMODULE module = GetModuleHandleA("ntdll.dll");
+ HANDLE file, map, event;
+ WCHAR path[MAX_PATH];
+ DWORD *names, *funcs;
+ WORD *ordinals;
+ ULONG size;
+ void *ptr;
+ int i;
+
+ GetModuleFileNameW(module, path, MAX_PATH);
+
+ file = CreateFileW(path, GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ ok(file != INVALID_HANDLE_VALUE, "Failed to open %s (error %u)\n", wine_dbgstr_w(path), GetLastError());
+
+ map = CreateFileMappingW(file, NULL, PAGE_EXECUTE_READ | SEC_IMAGE, 0, 0, NULL);
+ ok(map != NULL, "CreateFileMapping failed with error %u\n", GetLastError());
+ ptr = MapViewOfFile(map, FILE_MAP_READ | FILE_MAP_EXECUTE, 0, 0, 0);
+ ok(ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError());
+
+ dir = RtlImageDirectoryEntryToData(ptr, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
+todo_wine
+ ok(dir != NULL, "RtlImageDirectoryEntryToData failed\n");
+ if (dir == NULL) goto done;
+
+ names = RVAToAddr(dir->AddressOfNames, ptr);
+ ordinals = RVAToAddr(dir->AddressOfNameOrdinals, ptr);
+ funcs = RVAToAddr(dir->AddressOfFunctions, ptr);
+ ok(dir->NumberOfNames > 0, "Could not find any exported functions\n");
+
+ for (i = 0; i < dir->NumberOfNames; i++)
+ {
+ DWORD map_rva, dll_rva, map_offset, dll_offset;
+ char *func_name = RVAToAddr(names[i], ptr);
+ BYTE *dll_func, *map_func;
+
+ /* check only Nt functions for now */
+ if (strncmp(func_name, "Zw", 2) && strncmp(func_name, "Nt", 2))
+ continue;
+
+ dll_func = (BYTE *)GetProcAddress(module, func_name);
+ ok(dll_func != NULL, "%s: GetProcAddress returned NULL\n", func_name);
+ if (dll_func[0] == 0x90 && dll_func[1] == 0x90 &&
+ dll_func[2] == 0x90 && dll_func[3] == 0x90)
+ {
+ todo_wine ok(0, "%s: Export is a stub-function, skipping\n", func_name);
+ continue;
+ }
+
+ /* check position in memory */
+ dll_rva = (DWORD_PTR)dll_func - (DWORD_PTR)module;
+ map_rva = funcs[ordinals[i]];
+ ok(map_rva == dll_rva, "%s: Rva of mapped function (0x%x) does not match dll (0x%x)\n",
+ func_name, dll_rva, map_rva);
+
+ /* check position in file */
+ map_offset = (DWORD_PTR)RtlImageRvaToVa(RtlImageNtHeader(ptr), ptr, map_rva, NULL) - (DWORD_PTR)ptr;
+ dll_offset = (DWORD_PTR)RtlImageRvaToVa(RtlImageNtHeader(module), module, dll_rva, NULL) - (DWORD_PTR)module;
+ ok(map_offset == dll_offset, "%s: File offset of mapped function (0x%x) does not match dll (0x%x)\n",
+ func_name, map_offset, dll_offset);
+
+ /* check function content */
+ map_func = RVAToAddr(map_rva, ptr);
+ ok(!memcmp(map_func, dll_func, 0x20), "%s: Function content does not match!\n", func_name);
+
+ if (!strcmp(func_name, "NtSetEvent"))
+ pNtSetEvent = (void *)map_func;
+ }
+
+ ok(pNtSetEvent != NULL, "Could not find NtSetEvent export\n");
+ if (pNtSetEvent)
+ {
+ event = CreateEventA(NULL, TRUE, FALSE, NULL);
+ ok(event != NULL, "CreateEvent failed with error %u\n", GetLastError());
+ pNtSetEvent(event, 0);
+ ok(WaitForSingleObject(event, 0) == WAIT_OBJECT_0, "Event was not signaled\n");
+ CloseHandle(event);
+ }
+
+done:
+ UnmapViewOfFile(ptr);
+ CloseHandle(map);
+ CloseHandle(file);
+#endif
+}
+
/* Verify linking style of import descriptors */
static void test_ImportDescriptors(void)
{
@@ -4094,6 +4184,7 @@ START_TEST(loader)
return;
}
+ test_FakeDLL();
test_filenames();
test_ResolveDelayLoadedAPI();
test_ImportDescriptors();
--
2.26.2

View File

@ -1,660 +0,0 @@
From 7af81866f286e60f601d1c3f9bfe8592a794d21d Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 16 May 2017 04:37:52 +0200
Subject: [PATCH] krnl386.exe16: Do not abuse WOW32Reserved field for 16-bit
stack address.
---
dlls/dbghelp/cpu_i386.c | 6 ++---
dlls/krnl386.exe16/kernel.c | 6 ++---
dlls/krnl386.exe16/kernel16_private.h | 11 ++++----
dlls/krnl386.exe16/ne_module.c | 6 ++---
dlls/krnl386.exe16/ne_segment.c | 20 +++++++--------
dlls/krnl386.exe16/task.c | 14 +++++------
dlls/krnl386.exe16/thunk.c | 36 +++++++++++++--------------
dlls/krnl386.exe16/wowthunk.c | 20 +++++++--------
dlls/ntdll/unix/signal_i386.c | 2 +-
dlls/system.drv16/system.c | 2 +-
dlls/toolhelp.dll16/toolhelp.c | 6 ++---
dlls/user.exe16/message.c | 16 ++++++------
dlls/user.exe16/user.c | 4 +--
dlls/user.exe16/window.c | 2 +-
include/winternl.h | 2 +-
tools/winebuild/relay.c | 2 +-
16 files changed, 78 insertions(+), 77 deletions(-)
diff --git a/dlls/dbghelp/cpu_i386.c b/dlls/dbghelp/cpu_i386.c
index fd808a0d3248..7d6723977a29 100644
--- a/dlls/dbghelp/cpu_i386.c
+++ b/dlls/dbghelp/cpu_i386.c
@@ -213,16 +213,16 @@ static BOOL i386_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
/* Init done */
set_curr_mode((frame->AddrPC.Mode == AddrModeFlat) ? stm_32bit : stm_16bit);
- /* cur_switch holds address of WOW32Reserved field in TEB in debuggee
+ /* cur_switch holds address of SystemReserved1[0] field in TEB in debuggee
* address space
*/
if (NtQueryInformationThread(csw->hThread, ThreadBasicInformation, &info,
sizeof(info), NULL) == STATUS_SUCCESS)
{
- curr_switch = (DWORD_PTR)info.TebBaseAddress + FIELD_OFFSET(TEB, WOW32Reserved);
+ curr_switch = (DWORD_PTR)info.TebBaseAddress + FIELD_OFFSET(TEB, SystemReserved1[0]);
if (!sw_read_mem(csw, curr_switch, &p, sizeof(p)))
{
- WARN("Can't read TEB:WOW32Reserved\n");
+ WARN("Can't read TEB:SystemReserved1[0]\n");
goto done_err;
}
next_switch = p;
diff --git a/dlls/krnl386.exe16/kernel.c b/dlls/krnl386.exe16/kernel.c
index 07a57d0d9372..89ea5c042e71 100644
--- a/dlls/krnl386.exe16/kernel.c
+++ b/dlls/krnl386.exe16/kernel.c
@@ -47,8 +47,8 @@ static void thread_attach(void)
/* allocate the 16-bit stack (FIXME: should be done lazily) */
HGLOBAL16 hstack = WOWGlobalAlloc16( GMEM_FIXED, 0x10000 );
kernel_get_thread_data()->stack_sel = GlobalHandleToSel16( hstack );
- NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR( kernel_get_thread_data()->stack_sel,
- 0x10000 - sizeof(STACK16FRAME) );
+ NtCurrentTeb()->SystemReserved1[0] = (void *)MAKESEGPTR( kernel_get_thread_data()->stack_sel,
+ 0x10000 - sizeof(STACK16FRAME) );
memset( (char *)GlobalLock16(hstack) + 0x10000 - sizeof(STACK16FRAME), 0, sizeof(STACK16FRAME) );
}
@@ -60,7 +60,7 @@ static void thread_detach(void)
{
/* free the 16-bit stack */
WOWGlobalFree16( kernel_get_thread_data()->stack_sel );
- NtCurrentTeb()->WOW32Reserved = 0;
+ NtCurrentTeb()->SystemReserved1[0] = 0;
if (NtCurrentTeb()->Tib.SubSystemTib) TASK_ExitTask();
}
diff --git a/dlls/krnl386.exe16/kernel16_private.h b/dlls/krnl386.exe16/kernel16_private.h
index f15934daa0e4..9f939a9d5bac 100644
--- a/dlls/krnl386.exe16/kernel16_private.h
+++ b/dlls/krnl386.exe16/kernel16_private.h
@@ -169,7 +169,7 @@ extern THHOOK *pThhook DECLSPEC_HIDDEN;
(((offset)+(size) <= pModule->mapping_size) ? \
(memcpy( buffer, (const char *)pModule->mapping + (offset), (size) ), TRUE) : FALSE)
-#define CURRENT_STACK16 ((STACK16FRAME*)MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved)))
+#define CURRENT_STACK16 ((STACK16FRAME*)MapSL(PtrToUlong(NtCurrentTeb()->SystemReserved1[0])))
#define CURRENT_DS (CURRENT_STACK16->ds)
/* push bytes on the 16-bit stack of a thread; return a segptr to the first pushed byte */
@@ -177,8 +177,8 @@ static inline SEGPTR stack16_push( int size )
{
STACK16FRAME *frame = CURRENT_STACK16;
memmove( (char*)frame - size, frame, sizeof(*frame) );
- NtCurrentTeb()->WOW32Reserved = (char *)NtCurrentTeb()->WOW32Reserved - size;
- return (SEGPTR)((char *)NtCurrentTeb()->WOW32Reserved + sizeof(*frame));
+ NtCurrentTeb()->SystemReserved1[0] = (char *)NtCurrentTeb()->SystemReserved1[0] - size;
+ return (SEGPTR)((char *)NtCurrentTeb()->SystemReserved1[0] + sizeof(*frame));
}
/* pop bytes from the 16-bit stack of a thread */
@@ -186,7 +186,7 @@ static inline void stack16_pop( int size )
{
STACK16FRAME *frame = CURRENT_STACK16;
memmove( (char*)frame + size, frame, sizeof(*frame) );
- NtCurrentTeb()->WOW32Reserved = (char *)NtCurrentTeb()->WOW32Reserved + size;
+ NtCurrentTeb()->SystemReserved1[0] = (char *)NtCurrentTeb()->SystemReserved1[0] + size;
}
/* dosmem.c */
@@ -300,11 +300,12 @@ struct tagSYSLEVEL;
struct kernel_thread_data
{
+ void *reserved; /* stack segment pointer */
WORD stack_sel; /* 16-bit stack selector */
WORD htask16; /* Win16 task handle */
DWORD sys_count[4]; /* syslevel mutex entry counters */
struct tagSYSLEVEL *sys_mutex[4]; /* syslevel mutex pointers */
- void *pad[45]; /* change this if you add fields! */
+ void *pad[44]; /* change this if you add fields! */
};
static inline struct kernel_thread_data *kernel_get_thread_data(void)
diff --git a/dlls/krnl386.exe16/ne_module.c b/dlls/krnl386.exe16/ne_module.c
index f1e1a14dd679..c951a18f8699 100644
--- a/dlls/krnl386.exe16/ne_module.c
+++ b/dlls/krnl386.exe16/ne_module.c
@@ -1208,7 +1208,7 @@ DWORD NE_StartTask(void)
sp = pSegTable[SELECTOROF(pModule->ne_sssp)-1].minsize + pModule->ne_stack;
sp &= ~1;
sp -= sizeof(STACK16FRAME);
- NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR( GlobalHandleToSel16(hInstance), sp );
+ NtCurrentTeb()->SystemReserved1[0] = (void *)MAKESEGPTR( GlobalHandleToSel16(hInstance), sp );
/* Registers at initialization must be:
* ax zero
@@ -1236,8 +1236,8 @@ DWORD NE_StartTask(void)
TRACE("Starting main program: cs:ip=%04x:%04x ds=%04x ss:sp=%04x:%04x\n",
context.SegCs, context.Eip, context.SegDs,
- SELECTOROF(NtCurrentTeb()->WOW32Reserved),
- OFFSETOF(NtCurrentTeb()->WOW32Reserved) );
+ SELECTOROF(NtCurrentTeb()->SystemReserved1[0]),
+ OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) );
WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context );
ExitThread( LOWORD(context.Eax) );
diff --git a/dlls/krnl386.exe16/ne_segment.c b/dlls/krnl386.exe16/ne_segment.c
index aa8861480298..70eb33609144 100644
--- a/dlls/krnl386.exe16/ne_segment.c
+++ b/dlls/krnl386.exe16/ne_segment.c
@@ -370,9 +370,9 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
DWORD ret;
selfloadheader = MapSL( MAKESEGPTR(SEL(pSegTable->hSeg),0) );
- oldstack = NtCurrentTeb()->WOW32Reserved;
- NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR(pModule->self_loading_sel,
- 0xff00 - sizeof(STACK16FRAME));
+ oldstack = NtCurrentTeb()->SystemReserved1[0];
+ NtCurrentTeb()->SystemReserved1[0] = (void *)MAKESEGPTR(pModule->self_loading_sel,
+ 0xff00 - sizeof(STACK16FRAME));
hFile16 = NE_OpenFile( pModule );
TRACE_(dll)("Call LoadAppSegProc(hmodule=0x%04x,hf=%x,segnum=%d)\n",
@@ -384,7 +384,7 @@ BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum )
pSeg->hSeg = LOWORD(ret);
TRACE_(dll)("Ret LoadAppSegProc: hSeg=0x%04x\n", pSeg->hSeg);
_lclose16( hFile16 );
- NtCurrentTeb()->WOW32Reserved = oldstack;
+ NtCurrentTeb()->SystemReserved1[0] = oldstack;
pSeg->flags |= NE_SEGFLAGS_LOADED;
return TRUE;
@@ -476,9 +476,9 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
sel = GlobalAlloc16( GMEM_ZEROINIT, 0xFF00 );
pModule->self_loading_sel = SEL(sel);
FarSetOwner16( sel, pModule->self );
- oldstack = NtCurrentTeb()->WOW32Reserved;
- NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR(pModule->self_loading_sel,
- 0xff00 - sizeof(STACK16FRAME) );
+ oldstack = NtCurrentTeb()->SystemReserved1[0];
+ NtCurrentTeb()->SystemReserved1[0] = (void *)MAKESEGPTR(pModule->self_loading_sel,
+ 0xff00 - sizeof(STACK16FRAME) );
hFile16 = NE_OpenFile(pModule);
TRACE_(dll)("CallBootAppProc(hModule=0x%04x,hf=0x%04x)\n",
@@ -488,7 +488,7 @@ BOOL NE_LoadAllSegments( NE_MODULE *pModule )
WOWCallback16Ex( (DWORD)selfloadheader->BootApp, WCB16_PASCAL, sizeof(args), args, NULL );
TRACE_(dll)("Return from CallBootAppProc\n");
_lclose16(hFile16);
- NtCurrentTeb()->WOW32Reserved = oldstack;
+ NtCurrentTeb()->SystemReserved1[0] = oldstack;
for (i = 2; i <= pModule->ne_cseg; i++)
if (!NE_LoadSegment( pModule, i )) return FALSE;
@@ -680,7 +680,7 @@ static BOOL NE_InitDLL( NE_MODULE *pModule )
context.SegEs = ds; /* who knows ... */
context.SegCs = SEL(pSegTable[SELECTOROF(pModule->ne_csip)-1].hSeg);
context.Eip = OFFSETOF(pModule->ne_csip);
- context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + FIELD_OFFSET(STACK16FRAME,bp);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + FIELD_OFFSET(STACK16FRAME,bp);
pModule->ne_csip = 0; /* Don't initialize it twice */
TRACE_(dll)("Calling LibMain for %.*s, cs:ip=%04x:%04x ds=%04x di=%04x cx=%04x\n",
@@ -782,7 +782,7 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
context.SegEs = ds; /* who knows ... */
context.SegCs = HIWORD(entryPoint);
context.Eip = LOWORD(entryPoint);
- context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + FIELD_OFFSET(STACK16FRAME,bp);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + FIELD_OFFSET(STACK16FRAME,bp);
args[7] = HIWORD(dwReason);
args[6] = LOWORD(dwReason);
diff --git a/dlls/krnl386.exe16/task.c b/dlls/krnl386.exe16/task.c
index 39a60cb97a94..21de62c5a015 100644
--- a/dlls/krnl386.exe16/task.c
+++ b/dlls/krnl386.exe16/task.c
@@ -624,7 +624,7 @@ void WINAPI InitTask16( CONTEXT *context )
/* Initialize the INSTANCEDATA structure */
pinstance = MapSL( MAKESEGPTR(CURRENT_DS, 0) );
- pinstance->stackmin = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + sizeof( STACK16FRAME );
+ pinstance->stackmin = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + sizeof( STACK16FRAME );
pinstance->stackbottom = pinstance->stackmin; /* yup, that's right. Confused me too. */
pinstance->stacktop = ( pinstance->stackmin > LOWORD(context->Ebx) ?
pinstance->stackmin - LOWORD(context->Ebx) : 0 ) + 150;
@@ -1095,14 +1095,14 @@ void WINAPI SwitchStackTo16( WORD seg, WORD ptr, WORD top )
if (!(pData = GlobalLock16( seg ))) return;
TRACE("old=%04x:%04x new=%04x:%04x\n",
- SELECTOROF( NtCurrentTeb()->WOW32Reserved ),
- OFFSETOF( NtCurrentTeb()->WOW32Reserved ), seg, ptr );
+ SELECTOROF( NtCurrentTeb()->SystemReserved1[0] ),
+ OFFSETOF( NtCurrentTeb()->SystemReserved1[0] ), seg, ptr );
/* Save the old stack */
oldFrame = CURRENT_STACK16;
/* pop frame + args and push bp */
- pData->old_ss_sp = (SEGPTR)NtCurrentTeb()->WOW32Reserved + sizeof(STACK16FRAME)
+ pData->old_ss_sp = (SEGPTR)NtCurrentTeb()->SystemReserved1[0] + sizeof(STACK16FRAME)
+ 2 * sizeof(WORD);
*(WORD *)MapSL(pData->old_ss_sp) = oldFrame->bp;
pData->stacktop = top;
@@ -1116,7 +1116,7 @@ void WINAPI SwitchStackTo16( WORD seg, WORD ptr, WORD top )
*/
copySize = oldFrame->bp - OFFSETOF(pData->old_ss_sp);
copySize += 3 * sizeof(WORD) + sizeof(STACK16FRAME);
- NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR( seg, ptr - copySize );
+ NtCurrentTeb()->SystemReserved1[0] = (void *)MAKESEGPTR( seg, ptr - copySize );
newFrame = CURRENT_STACK16;
/* Copy the stack frame and the local variables to the new stack */
@@ -1135,7 +1135,7 @@ void WINAPI SwitchStackBack16( CONTEXT *context )
STACK16FRAME *oldFrame, *newFrame;
INSTANCEDATA *pData;
- if (!(pData = GlobalLock16(SELECTOROF(NtCurrentTeb()->WOW32Reserved))))
+ if (!(pData = GlobalLock16(SELECTOROF(NtCurrentTeb()->SystemReserved1[0]))))
return;
if (!pData->old_ss_sp)
{
@@ -1154,7 +1154,7 @@ void WINAPI SwitchStackBack16( CONTEXT *context )
/* Switch back to the old stack */
- NtCurrentTeb()->WOW32Reserved = (void *)(pData->old_ss_sp - sizeof(STACK16FRAME));
+ NtCurrentTeb()->SystemReserved1[0] = (void *)(pData->old_ss_sp - sizeof(STACK16FRAME));
context->SegSs = SELECTOROF(pData->old_ss_sp);
context->Esp = OFFSETOF(pData->old_ss_sp) - sizeof(DWORD); /*ret addr*/
pData->old_ss_sp = 0;
diff --git a/dlls/krnl386.exe16/thunk.c b/dlls/krnl386.exe16/thunk.c
index e913a08f88cc..ecc94371488f 100644
--- a/dlls/krnl386.exe16/thunk.c
+++ b/dlls/krnl386.exe16/thunk.c
@@ -429,7 +429,7 @@ void WINAPI __regs_QT_Thunk( CONTEXT *context )
context16.Eip = LOWORD(context->Edx);
/* point EBP to the STACK16FRAME on the stack
* for the call_to_16 to set up the register content on calling */
- context16.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + FIELD_OFFSET(STACK16FRAME,bp);
+ context16.Ebp = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + FIELD_OFFSET(STACK16FRAME,bp);
/*
* used to be (problematic):
@@ -451,7 +451,7 @@ void WINAPI __regs_QT_Thunk( CONTEXT *context )
* the number of parameters that the Win16 function
* accepted (that it popped from the corresponding Win16 stack) */
context->Esp += LOWORD(context16.Esp) -
- ( OFFSETOF(NtCurrentTeb()->WOW32Reserved) - argsize );
+ ( OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) - argsize );
}
DEFINE_REGS_ENTRYPOINT( QT_Thunk )
@@ -555,7 +555,7 @@ void WINAPI __regs_FT_Thunk( CONTEXT *context )
context16.SegCs = HIWORD(callTarget);
context16.Eip = LOWORD(callTarget);
- context16.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + FIELD_OFFSET(STACK16FRAME,bp);
+ context16.Ebp = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + FIELD_OFFSET(STACK16FRAME,bp);
argsize = context->Ebp-context->Esp-0x40;
if (argsize > sizeof(newstack)) argsize = sizeof(newstack);
@@ -567,8 +567,8 @@ void WINAPI __regs_FT_Thunk( CONTEXT *context )
if (mapESPrelative & (1 << i))
{
SEGPTR *arg = (SEGPTR *)newstack[i];
- *arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->WOW32Reserved),
- OFFSETOF(NtCurrentTeb()->WOW32Reserved) - argsize
+ *arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->SystemReserved1[0]),
+ OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) - argsize
+ (*(LPBYTE *)arg - oldstack));
}
@@ -578,7 +578,7 @@ void WINAPI __regs_FT_Thunk( CONTEXT *context )
context->Ecx = context16.Ecx;
context->Esp += LOWORD(context16.Esp) -
- ( OFFSETOF(NtCurrentTeb()->WOW32Reserved) - argsize );
+ ( OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) - argsize );
/* Copy modified buffers back to 32-bit stack */
memcpy( oldstack, newstack, argsize );
@@ -713,7 +713,7 @@ void WINAPI __regs_Common32ThkLS( CONTEXT *context )
context16.Edi = LOWORD(context->Ecx);
context16.SegCs = HIWORD(context->Eax);
context16.Eip = LOWORD(context->Eax);
- context16.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + FIELD_OFFSET(STACK16FRAME,bp);
+ context16.Ebp = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + FIELD_OFFSET(STACK16FRAME,bp);
argsize = HIWORD(context->Edx) * 4;
@@ -769,7 +769,7 @@ void WINAPI __regs_OT_32ThkLSF( CONTEXT *context )
context16.SegCs = HIWORD(context->Edx);
context16.Eip = LOWORD(context->Edx);
- context16.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + FIELD_OFFSET(STACK16FRAME,bp);
+ context16.Ebp = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + FIELD_OFFSET(STACK16FRAME,bp);
argsize = 2 * *(WORD *)context->Esp + 2;
@@ -782,7 +782,7 @@ void WINAPI __regs_OT_32ThkLSF( CONTEXT *context )
(LPBYTE)CURRENT_STACK16 - argsize, argsize );
context->Esp += LOWORD(context16.Esp) -
- ( OFFSETOF(NtCurrentTeb()->WOW32Reserved) - argsize );
+ ( OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) - argsize );
}
DEFINE_REGS_ENTRYPOINT( OT_32ThkLSF )
@@ -1234,26 +1234,26 @@ void WINAPI __regs_K32Thk1632Prolog( CONTEXT *context )
DWORD argSize = context->Ebp - context->Esp;
char *stack16 = (char *)context->Esp - 4;
STACK16FRAME *frame16 = (STACK16FRAME *)stack16 - 1;
- STACK32FRAME *frame32 = NtCurrentTeb()->WOW32Reserved;
+ STACK32FRAME *frame32 = NtCurrentTeb()->SystemReserved1[0];
char *stack32 = (char *)frame32 - argSize;
WORD stackSel = SELECTOROF(frame32->frame16);
DWORD stackBase = GetSelectorBase(stackSel);
TRACE("before SYSTHUNK hack: EBP: %08x ESP: %08x cur_stack: %p\n",
- context->Ebp, context->Esp, NtCurrentTeb()->WOW32Reserved);
+ context->Ebp, context->Esp, NtCurrentTeb()->SystemReserved1[0]);
memset(frame16, '\0', sizeof(STACK16FRAME));
frame16->frame32 = frame32;
frame16->ebp = context->Ebp;
memcpy(stack32, stack16, argSize);
- NtCurrentTeb()->WOW32Reserved = (void *)MAKESEGPTR(stackSel, (DWORD)frame16 - stackBase);
+ NtCurrentTeb()->SystemReserved1[0] = (void *)MAKESEGPTR(stackSel, (DWORD)frame16 - stackBase);
context->Esp = (DWORD)stack32 + 4;
context->Ebp = context->Esp + argSize;
TRACE("after SYSTHUNK hack: EBP: %08x ESP: %08x cur_stack: %p\n",
- context->Ebp, context->Esp, NtCurrentTeb()->WOW32Reserved);
+ context->Ebp, context->Esp, NtCurrentTeb()->SystemReserved1[0]);
}
/* entry_point is never used again once the entry point has
@@ -1276,7 +1276,7 @@ void WINAPI __regs_K32Thk1632Epilog( CONTEXT *context )
if ( code[5] == 0xFF && code[6] == 0x55 && code[7] == 0xFC
&& code[13] == 0x66 && code[14] == 0xCB)
{
- STACK16FRAME *frame16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
+ STACK16FRAME *frame16 = MapSL((SEGPTR)NtCurrentTeb()->SystemReserved1[0]);
char *stack16 = (char *)(frame16 + 1);
DWORD argSize = frame16->ebp - (DWORD)stack16;
char *stack32 = (char *)frame16->frame32 - argSize;
@@ -1284,15 +1284,15 @@ void WINAPI __regs_K32Thk1632Epilog( CONTEXT *context )
DWORD nArgsPopped = context->Esp - (DWORD)stack32;
TRACE("before SYSTHUNK hack: EBP: %08x ESP: %08x cur_stack: %p\n",
- context->Ebp, context->Esp, NtCurrentTeb()->WOW32Reserved);
+ context->Ebp, context->Esp, NtCurrentTeb()->SystemReserved1[0]);
- NtCurrentTeb()->WOW32Reserved = frame16->frame32;
+ NtCurrentTeb()->SystemReserved1[0] = frame16->frame32;
context->Esp = (DWORD)stack16 + nArgsPopped;
context->Ebp = frame16->ebp;
TRACE("after SYSTHUNK hack: EBP: %08x ESP: %08x cur_stack: %p\n",
- context->Ebp, context->Esp, NtCurrentTeb()->WOW32Reserved);
+ context->Ebp, context->Esp, NtCurrentTeb()->SystemReserved1[0]);
}
}
DEFINE_REGS_ENTRYPOINT( K32Thk1632Epilog )
@@ -2303,7 +2303,7 @@ void WINAPI Throw16( LPCATCHBUF lpbuf, INT16 retval, CONTEXT *context )
frame32 = pFrame->frame32;
while (frame32 && frame32->frame16)
{
- if (OFFSETOF(frame32->frame16) < OFFSETOF(NtCurrentTeb()->WOW32Reserved))
+ if (OFFSETOF(frame32->frame16) < OFFSETOF(NtCurrentTeb()->SystemReserved1[0]))
break; /* Something strange is going on */
if (OFFSETOF(frame32->frame16) > lpbuf[2])
{
diff --git a/dlls/krnl386.exe16/wowthunk.c b/dlls/krnl386.exe16/wowthunk.c
index 2dddbf932898..3a4b104a673f 100644
--- a/dlls/krnl386.exe16/wowthunk.c
+++ b/dlls/krnl386.exe16/wowthunk.c
@@ -127,7 +127,7 @@ static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RE
{
/* unwinding: restore the stack pointer in the TEB, and leave the Win16 mutex */
STACK32FRAME *frame32 = CONTAINING_RECORD(frame, STACK32FRAME, frame);
- NtCurrentTeb()->WOW32Reserved = (void *)frame32->frame16;
+ NtCurrentTeb()->SystemReserved1[0] = (void *)frame32->frame16;
_LeaveWin16Lock();
}
else if (record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
@@ -412,8 +412,8 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
TRACE_(relay)( "\1CallTo16(func=%04x:%04x", context->SegCs, LOWORD(context->Eip) );
while (count) TRACE_(relay)( ",%04x", wstack[--count] );
TRACE_(relay)( ") ss:sp=%04x:%04x ax=%04x bx=%04x cx=%04x dx=%04x si=%04x di=%04x bp=%04x ds=%04x es=%04x\n",
- SELECTOROF(NtCurrentTeb()->WOW32Reserved),
- OFFSETOF(NtCurrentTeb()->WOW32Reserved),
+ SELECTOROF(NtCurrentTeb()->SystemReserved1[0]),
+ OFFSETOF(NtCurrentTeb()->SystemReserved1[0]),
(WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx,
(WORD)context->Edx, (WORD)context->Esi, (WORD)context->Edi,
(WORD)context->Ebp, (WORD)context->SegDs, (WORD)context->SegEs );
@@ -443,8 +443,8 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
if (TRACE_ON(relay))
{
TRACE_(relay)( "\1RetFrom16() ss:sp=%04x:%04x ax=%04x bx=%04x cx=%04x dx=%04x bp=%04x sp=%04x\n",
- SELECTOROF(NtCurrentTeb()->WOW32Reserved),
- OFFSETOF(NtCurrentTeb()->WOW32Reserved),
+ SELECTOROF(NtCurrentTeb()->SystemReserved1[0]),
+ OFFSETOF(NtCurrentTeb()->SystemReserved1[0]),
(WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx,
(WORD)context->Edx, (WORD)context->Ebp, (WORD)context->Esp );
SYSLEVEL_CheckNotLevel( 2 );
@@ -460,10 +460,10 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
WORD * wstack = (WORD *)stack;
TRACE_(relay)( "\1CallTo16(func=%04x:%04x,ds=%04x",
- HIWORD(vpfn16), LOWORD(vpfn16), SELECTOROF(NtCurrentTeb()->WOW32Reserved) );
+ HIWORD(vpfn16), LOWORD(vpfn16), SELECTOROF(NtCurrentTeb()->SystemReserved1[0]) );
while (count) TRACE_(relay)( ",%04x", wstack[--count] );
- TRACE_(relay)( ") ss:sp=%04x:%04x\n", SELECTOROF(NtCurrentTeb()->WOW32Reserved),
- OFFSETOF(NtCurrentTeb()->WOW32Reserved) );
+ TRACE_(relay)( ") ss:sp=%04x:%04x\n", SELECTOROF(NtCurrentTeb()->SystemReserved1[0]),
+ OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) );
SYSLEVEL_CheckNotLevel( 2 );
}
@@ -486,8 +486,8 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
if (TRACE_ON(relay))
{
TRACE_(relay)( "\1RetFrom16() ss:sp=%04x:%04x retval=%08x\n",
- SELECTOROF(NtCurrentTeb()->WOW32Reserved),
- OFFSETOF(NtCurrentTeb()->WOW32Reserved), ret );
+ SELECTOROF(NtCurrentTeb()->SystemReserved1[0]),
+ OFFSETOF(NtCurrentTeb()->SystemReserved1[0]), ret );
SYSLEVEL_CheckNotLevel( 2 );
}
}
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index ac34f86a5883..55f1e2ce4b23 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -645,7 +645,7 @@ static inline void *init_handler( const ucontext_t *sigcontext )
* SS is still non-system segment. This is why both CS and SS
* are checked.
*/
- return teb->WOW32Reserved;
+ return teb->SystemReserved1[0];
}
return (void *)(ESP_sig(sigcontext) & ~3);
}
diff --git a/dlls/system.drv16/system.c b/dlls/system.drv16/system.c
index b6fd51c05f01..695ad7b60039 100644
--- a/dlls/system.drv16/system.c
+++ b/dlls/system.drv16/system.c
@@ -70,7 +70,7 @@ static void CALLBACK SYSTEM_TimerTick( LPVOID arg, DWORD low, DWORD high )
memset( &context, 0, sizeof(context) );
context.SegCs = SELECTOROF( proc );
context.Eip = OFFSETOF( proc );
- context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + FIELD_OFFSET(STACK16FRAME, bp);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + FIELD_OFFSET(STACK16FRAME, bp);
context.Eax = i + 1;
WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context );
diff --git a/dlls/toolhelp.dll16/toolhelp.c b/dlls/toolhelp.dll16/toolhelp.c
index 578d1ae7faba..1077f0b03672 100644
--- a/dlls/toolhelp.dll16/toolhelp.c
+++ b/dlls/toolhelp.dll16/toolhelp.c
@@ -491,8 +491,8 @@ BOOL16 WINAPI TaskNext16( TASKENTRY *lpte )
lpte->hTaskParent = pTask->hParent;
lpte->hInst = pTask->hInstance;
lpte->hModule = pTask->hModule;
- lpte->wSS = SELECTOROF( pTask->teb->WOW32Reserved );
- lpte->wSP = OFFSETOF( pTask->teb->WOW32Reserved );
+ lpte->wSS = SELECTOROF( pTask->teb->SystemReserved1[0] );
+ lpte->wSP = OFFSETOF( pTask->teb->SystemReserved1[0] );
lpte->wStackTop = pInstData->stacktop;
lpte->wStackMinimum = pInstData->stackmin;
lpte->wStackBottom = pInstData->stackbottom;
@@ -718,7 +718,7 @@ BOOL16 WINAPI TimerCount16( TIMERINFO *pTimerInfo )
*/
BOOL16 WINAPI SystemHeapInfo16( SYSHEAPINFO *pHeapInfo )
{
- STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
+ STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->SystemReserved1[0]);
HANDLE16 oldDS = stack16->ds;
WORD user = LoadLibrary16( "USER.EXE" );
WORD gdi = LoadLibrary16( "GDI.EXE" );
diff --git a/dlls/user.exe16/message.c b/dlls/user.exe16/message.c
index e3ca3fd779d3..fa9388ceaa11 100644
--- a/dlls/user.exe16/message.c
+++ b/dlls/user.exe16/message.c
@@ -240,11 +240,11 @@ static LRESULT call_window_proc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPA
/* Window procedures want ax = hInstance, ds = es = ss */
memset(&context, 0, sizeof(context));
- context.SegDs = context.SegEs = SELECTOROF(NtCurrentTeb()->WOW32Reserved);
+ context.SegDs = context.SegEs = SELECTOROF(NtCurrentTeb()->SystemReserved1[0]);
if (!(context.Eax = GetWindowWord( HWND_32(hwnd), GWLP_HINSTANCE ))) context.Eax = context.SegDs;
context.SegCs = SELECTOROF(func);
context.Eip = OFFSETOF(func);
- context.Ebp = OFFSETOF(NtCurrentTeb()->WOW32Reserved) + FIELD_OFFSET(STACK16FRAME, bp);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->SystemReserved1[0]) + FIELD_OFFSET(STACK16FRAME, bp);
if (lParam)
{
@@ -267,7 +267,7 @@ static LRESULT call_window_proc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LPA
if (size)
{
memcpy( &args.u, MapSL(lParam), size );
- lParam = PtrToUlong(NtCurrentTeb()->WOW32Reserved) - size;
+ lParam = PtrToUlong(NtCurrentTeb()->SystemReserved1[0]) - size;
}
}
@@ -2092,7 +2092,7 @@ static LRESULT combo_proc16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
static void edit_lock_buffer( HWND hwnd )
{
- STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->SystemReserved1[0]));
HLOCAL16 hloc16 = GetWindowWord( hwnd, GWW_HANDLE16 );
HANDLE16 oldDS;
HLOCAL hloc32;
@@ -2118,7 +2118,7 @@ static void edit_lock_buffer( HWND hwnd )
static void edit_unlock_buffer( HWND hwnd )
{
- STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->SystemReserved1[0]));
HLOCAL16 hloc16 = GetWindowWord( hwnd, GWW_HANDLE16 );
HANDLE16 oldDS;
HLOCAL hloc32;
@@ -2155,7 +2155,7 @@ static HLOCAL16 edit_get_handle( HWND hwnd )
if (!(hloc = (HLOCAL)wow_handlers32.edit_proc( hwnd, EM_GETHANDLE, 0, 0, FALSE ))) return 0;
alloc_size = LocalSize( hloc );
- stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ stack16 = MapSL(PtrToUlong(NtCurrentTeb()->SystemReserved1[0]));
oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
@@ -2193,7 +2193,7 @@ done:
static void edit_set_handle( HWND hwnd, HLOCAL16 hloc16 )
{
- STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->SystemReserved1[0]));
HINSTANCE16 hInstance = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
HANDLE16 oldDS = stack16->ds;
HLOCAL hloc32;
@@ -2223,7 +2223,7 @@ static void edit_destroy_handle( HWND hwnd )
HLOCAL16 hloc16 = GetWindowWord( hwnd, GWW_HANDLE16 );
if (hloc16)
{
- STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
+ STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->SystemReserved1[0]));
HANDLE16 oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
diff --git a/dlls/user.exe16/user.c b/dlls/user.exe16/user.c
index 27b92793836a..deec596f7660 100644
--- a/dlls/user.exe16/user.c
+++ b/dlls/user.exe16/user.c
@@ -1394,7 +1394,7 @@ DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
*/
DWORD WINAPI UserSeeUserDo16(WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3)
{
- STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
+ STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->SystemReserved1[0]);
HANDLE16 oldDS = stack16->ds;
DWORD ret = (DWORD)-1;
@@ -1787,7 +1787,7 @@ UINT16 WINAPI RealizePalette16( HDC16 hdc )
*/
WORD WINAPI GetFreeSystemResources16( WORD resType )
{
- STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
+ STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->SystemReserved1[0]);
HANDLE16 oldDS = stack16->ds;
int userPercent, gdiPercent;
diff --git a/dlls/user.exe16/window.c b/dlls/user.exe16/window.c
index bf86719325b8..1f53bdc95402 100644
--- a/dlls/user.exe16/window.c
+++ b/dlls/user.exe16/window.c
@@ -456,7 +456,7 @@ HWND16 WINAPI GetParent16( HWND16 hwnd )
*/
BOOL16 WINAPI IsWindow16( HWND16 hwnd )
{
- STACK16FRAME *frame = MapSL( (SEGPTR)NtCurrentTeb()->WOW32Reserved );
+ STACK16FRAME *frame = MapSL( (SEGPTR)NtCurrentTeb()->SystemReserved1[0] );
frame->es = USER_HeapSel;
/* don't use WIN_Handle32 here, we don't care about the full handle */
return IsWindow( HWND_32(hwnd) );
diff --git a/include/winternl.h b/include/winternl.h
index 87eb0d32926b..2d9f54b89d8c 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -363,7 +363,7 @@ typedef struct _TEB
PVOID WOW32Reserved; /* 0c0/0100 */
ULONG CurrentLocale; /* 0c4/0108 */
ULONG FpSoftwareStatusRegister; /* 0c8/010c */
- PVOID SystemReserved1[54]; /* 0cc/0110 used for kernel32 private data in Wine */
+ PVOID SystemReserved1[54]; /* 0cc/0110 used for krnl386.exe16 private data in Wine */
LONG ExceptionCode; /* 1a4/02c0 */
ACTIVATION_CONTEXT_STACK ActivationContextStack; /* 1a8/02c8 */
BYTE SpareBytes1[24]; /* 1bc/02e8 */
diff --git a/tools/winebuild/relay.c b/tools/winebuild/relay.c
index 29d0a74c833c..01bb97e02b4c 100644
--- a/tools/winebuild/relay.c
+++ b/tools/winebuild/relay.c
@@ -31,7 +31,7 @@
#include "build.h"
/* offset of the stack pointer relative to %fs:(0) */
-#define STACKOFFSET 0xc0 /* FIELD_OFFSET(TEB,WOW32Reserved) */
+#define STACKOFFSET 0xcc /* FIELD_OFFSET(TEB,SystemReserved1[0]) */
/* fix this if the x86_thread_data structure is changed */
#define GS_OFFSET 0x1d8 /* FIELD_OFFSET(TEB,SystemReserved2) + FIELD_OFFSET(struct x86_thread_data,gs) */
--
2.26.2

View File

@ -1,554 +0,0 @@
From 9cbc0d6d9404dc93016ba7db6a10a2cad873cbba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 11 May 2017 05:32:55 +0200
Subject: [PATCH] winebuild: Generate syscall thunks for ntdll exports.
Based on a patch by Erich E. Hoover.
---
dlls/ntdll/loader.c | 3 +
dlls/ntdll/signal_i386.c | 4 +-
dlls/ntdll/tests/exception.c | 2 +
dlls/ntdll/thread.c | 10 +++-
dlls/ntdll/unix/thread.c | 3 +-
dlls/ntdll/unix/unix_private.h | 2 +-
dlls/ntdll/unixlib.h | 2 +-
include/winternl.h | 2 +-
tools/winebuild/build.h | 7 +++
tools/winebuild/import.c | 10 ++--
tools/winebuild/parser.c | 59 +++++++++++++++++++
tools/winebuild/spec16.c | 22 +------
tools/winebuild/spec32.c | 104 +++++++++++++++++++++++++++++++++
tools/winebuild/utils.c | 21 +++++++
14 files changed, 220 insertions(+), 31 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 42cdc628021..339b54a9e67 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -3387,6 +3387,7 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
return ret;
}
+extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
/******************************************************************
* LdrInitializeThunk (NTDLL.@)
@@ -3403,6 +3404,8 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow
WINE_MODREF *wm;
LPCWSTR load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
+ NtCurrentTeb()->WOW32Reserved = __wine_syscall_dispatcher;
+
if (process_detaching) return;
RtlEnterCriticalSection( &loader_section );
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index bda19bf4632..5dccee926b9 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -336,6 +336,8 @@ __ASM_STDCALL_FUNC( RtlCaptureContext, 4,
"ret $4" )
+extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context );
+
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
@@ -360,7 +362,7 @@ NTSTATUS CDECL DECLSPEC_HIDDEN __regs_NtGetContextThread( DWORD edi, DWORD esi,
{
context->Ebp = ebp;
context->Esp = (DWORD)&retaddr;
- context->Eip = *(&edi - 1);
+ context->Eip = (DWORD)__syscall_NtGetContextThread + 18;
context->EFlags = eflags;
}
return unix_funcs->NtGetContextThread( handle, context );
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 411439f180f..cd019fd5add 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -1643,6 +1643,8 @@ static void test_thread_context(void)
ok( (char *)context.Eip >= (char *)pNtGetContextThread - 0x40000 &&
(char *)context.Eip <= (char *)pNtGetContextThread + 0x40000,
"wrong Eip %08x/%08x\n", context.Eip, (DWORD)pNtGetContextThread );
+ ok( *(WORD *)context.Eip == 0xc483 || *(WORD *)context.Eip == 0x08c2 || *(WORD *)context.Eip == 0x8dc3,
+ "expected 0xc483 or 0x08c2 or 0x8dc3, got %04x\n", *(WORD *)context.Eip );
/* segment registers clear the high word */
ok( context.SegCs == LOWORD(expect.SegCs), "wrong SegCs %08x/%08x\n", context.SegCs, expect.SegCs );
ok( context.SegDs == LOWORD(expect.SegDs), "wrong SegDs %08x/%08x\n", context.SegDs, expect.SegDs );
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index fc57f186544..780b3b153da 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -94,6 +94,14 @@ int __cdecl __wine_dbg_output( const char *str )
return unix_funcs->dbg_output( str );
}
+#if defined(__i386__) || defined(__x86_64__)
+extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void );
+#else
+void __wine_syscall_dispatcher( void )
+{
+ FIXME("Syscall dispatcher is not available for this architecture.\n");
+}
+#endif
/***********************************************************************
* thread_init
@@ -105,7 +113,7 @@ int __cdecl __wine_dbg_output( const char *str )
TEB *thread_init( SIZE_T *info_size )
{
ULONG_PTR val;
- TEB *teb = unix_funcs->init_threading( &nb_threads, &__wine_ldt_copy, info_size );
+ TEB *teb = unix_funcs->init_threading( &nb_threads, &__wine_ldt_copy, info_size, __wine_syscall_dispatcher );
peb = teb->Peb;
peb->FastPebLock = &peb_lock;
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index f3dddd2b02a..7952497645e 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -84,7 +84,7 @@ static void pthread_exit_wrapper( int status )
/***********************************************************************
* init_threading
*/
-TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size )
+TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size, void *syscall_handler )
{
TEB *teb;
BOOL suspend;
@@ -96,6 +96,7 @@ TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZ
nb_threads = nb_threads_ptr;
teb = virtual_alloc_first_teb();
+ teb->WOW32Reserved = syscall_handler;
signal_init_threading();
signal_alloc_thread( teb );
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 707ca819e0e..72987a0041b 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -115,7 +115,7 @@ extern NTSTATUS CDECL server_handle_to_fd( HANDLE handle, unsigned int access, i
unsigned int *options ) DECLSPEC_HIDDEN;
extern void CDECL server_release_fd( HANDLE handle, int unix_fd ) DECLSPEC_HIDDEN;
extern void CDECL server_init_process_done( void *relay ) DECLSPEC_HIDDEN;
-extern TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size ) DECLSPEC_HIDDEN;
+extern TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size, void *syscall_handler ) DECLSPEC_HIDDEN;
extern void CDECL DECLSPEC_NORETURN exit_thread( int status ) DECLSPEC_HIDDEN;
extern void CDECL DECLSPEC_NORETURN exit_process( int status ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL exec_process( UNICODE_STRING *path, UNICODE_STRING *cmdline, NTSTATUS status ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h
index b14adce4a70..b5b7cb07c80 100644
--- a/dlls/ntdll/unixlib.h
+++ b/dlls/ntdll/unixlib.h
@@ -304,7 +304,7 @@ struct unix_funcs
void (CDECL *virtual_set_large_address_space)(void);
/* thread/process functions */
- TEB * (CDECL *init_threading)( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size );
+ TEB * (CDECL *init_threading)( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZE_T *size, void *syscall_handler );
void (CDECL *exit_thread)( int status );
void (CDECL *exit_process)( int status );
NTSTATUS (CDECL *exec_process)( UNICODE_STRING *path, UNICODE_STRING *cmdline, NTSTATUS status );
diff --git a/include/winternl.h b/include/winternl.h
index 34d2737b705..ef848272f7f 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -359,7 +359,7 @@ typedef struct _TEB
PVOID CsrClientThread; /* 03c/0070 */
PVOID Win32ThreadInfo; /* 040/0078 */
ULONG Win32ClientInfo[31]; /* 044/0080 used for user32 private data in Wine */
- PVOID WOW32Reserved; /* 0c0/0100 */
+ PVOID WOW32Reserved; /* 0c0/0100 used for ntdll syscall thunks */
ULONG CurrentLocale; /* 0c4/0108 */
ULONG FpSoftwareStatusRegister; /* 0c8/010c */
PVOID SystemReserved1[54]; /* 0cc/0110 used for krnl386.exe16 private data in Wine */
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h
index c162888a035..55d5b0b9dc2 100644
--- a/tools/winebuild/build.h
+++ b/tools/winebuild/build.h
@@ -105,6 +105,7 @@ typedef struct
int flags;
char *name; /* public name of this function */
char *link_name; /* name of the C symbol to link to */
+ char *impl_name; /* name of the C symbol of the real implementation (thunks only) */
char *export_name; /* name exported under for noname exports */
union
{
@@ -131,6 +132,7 @@ typedef struct
int alloc_entry_points; /* number of allocated entry points */
int nb_names; /* number of entry points with names */
unsigned int nb_resources; /* number of resources */
+ int nb_syscalls; /* number of syscalls */
int characteristics; /* characteristics for the PE header */
int dll_characteristics;/* DLL characteristics for the PE header */
int subsystem; /* subsystem id */
@@ -140,6 +142,7 @@ typedef struct
ORDDEF **names; /* array of entry point names (points into entry_points) */
ORDDEF **ordinals; /* array of dll ordinals (points into entry_points) */
struct resource *resources; /* array of dll resources (format differs between Win16/Win32) */
+ ORDDEF **syscalls; /* array of syscalls (points into entry_points) */
} DLLSPEC;
enum target_cpu
@@ -182,8 +185,10 @@ struct strarray
#define FLAG_FORWARD 0x1000 /* function is a forwarded name */
#define FLAG_EXT_LINK 0x2000 /* function links to an external symbol */
#define FLAG_EXPORT32 0x4000 /* 32-bit export in 16-bit spec file */
+#define FLAG_SYSCALL 0x8000 /* function should be called through a syscall thunk */
#define FLAG_CPU(cpu) (0x10000 << (cpu))
+
#define FLAG_CPU_MASK (FLAG_CPU(CPU_LAST + 1) - FLAG_CPU(0))
#define FLAG_CPU_WIN64 (FLAG_CPU(CPU_x86_64) | FLAG_CPU(CPU_ARM64))
#define FLAG_CPU_WIN32 (FLAG_CPU_MASK & ~FLAG_CPU_WIN64)
@@ -327,6 +332,8 @@ extern void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 );
extern int parse_spec_file( FILE *file, DLLSPEC *spec );
extern int parse_def_file( FILE *file, DLLSPEC *spec );
+extern int sort_func_list( ORDDEF **list, int count, int (*compare)(const void *, const void *) );
+
/* buffer management */
extern int byte_swapped;
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 04ab433dd65..0c6bafed8e5 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -531,6 +531,7 @@ static void check_undefined_forwards( DLLSPEC *spec )
/* flag the dll exports that link to an undefined symbol */
static void check_undefined_exports( DLLSPEC *spec )
{
+ const char *name;
int i;
for (i = 0; i < spec->nb_entry_points; i++)
@@ -538,7 +539,8 @@ static void check_undefined_exports( DLLSPEC *spec )
ORDDEF *odp = &spec->entry_points[i];
if (odp->type == TYPE_STUB || odp->type == TYPE_ABS || odp->type == TYPE_VARIABLE) continue;
if (odp->flags & FLAG_FORWARD) continue;
- if (find_name( odp->link_name, &undef_symbols ))
+ name = odp->impl_name ? odp->impl_name : odp->link_name;
+ if (find_name( name, &undef_symbols ))
{
switch(odp->type)
{
@@ -549,14 +551,14 @@ static void check_undefined_exports( DLLSPEC *spec )
if (link_ext_symbols)
{
odp->flags |= FLAG_EXT_LINK;
- strarray_add( &ext_link_imports, odp->link_name, NULL );
+ strarray_add( &ext_link_imports, name, NULL );
}
else error( "%s:%d: function '%s' not defined\n",
- spec->src_name, odp->lineno, odp->link_name );
+ spec->src_name, odp->lineno, name );
break;
default:
error( "%s:%d: external symbol '%s' is not a function\n",
- spec->src_name, odp->lineno, odp->link_name );
+ spec->src_name, odp->lineno, name );
break;
}
}
diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c
index 0207b8ac3c3..91f596f1d2d 100644
--- a/tools/winebuild/parser.c
+++ b/tools/winebuild/parser.c
@@ -543,6 +543,24 @@ static const char *parse_spec_flags( DLLSPEC *spec, ORDDEF *odp )
}
+static int needs_syscall( ORDDEF *odp, DLLSPEC *spec )
+{
+ if (target_cpu != CPU_x86)
+ return 0;
+ if (odp->flags & (FLAG_FORWARD | FLAG_REGISTER))
+ return 0;
+ if (odp->type != TYPE_STDCALL)
+ return 0;
+ if (!spec->dll_name || strcmp(spec->dll_name, "ntdll"))
+ return 0;
+ if (!odp->name)
+ return 0;
+ if (strncmp(odp->name, "Nt", 2) && strncmp(odp->name, "Zw", 2))
+ return 0;
+ return 1;
+}
+
+
/*******************************************************************
* parse_spec_ordinal
*
@@ -618,6 +636,14 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
assert( 0 );
}
+ if (needs_syscall( odp, spec ))
+ {
+ char *link_name = strmake( "__syscall_%s", odp->link_name );
+ odp->impl_name = odp->link_name;
+ odp->link_name = link_name;
+ odp->flags |= FLAG_SYSCALL;
+ }
+
if ((odp->flags & FLAG_CPU_MASK) && !(odp->flags & FLAG_CPU(target_cpu)))
{
/* ignore this entry point */
@@ -815,6 +841,37 @@ static void assign_ordinals( DLLSPEC *spec )
}
+static int link_name_compare( const void *e1, const void *e2 )
+{
+ const ORDDEF *odp1 = *(const ORDDEF * const *)e1;
+ const ORDDEF *odp2 = *(const ORDDEF * const *)e2;
+ return strcmp(odp1->link_name, odp2->link_name);
+}
+
+
+static void assign_syscalls( DLLSPEC *spec )
+{
+ int i;
+
+ spec->syscalls = xmalloc( (spec->limit - spec->base + 1) * sizeof(*spec->syscalls) );
+ spec->nb_syscalls = 0;
+
+ for (i = 0; i <= spec->limit; i++)
+ {
+ ORDDEF *odp = spec->ordinals[i];
+ if (!odp || !(odp->flags & FLAG_SYSCALL)) continue;
+ spec->syscalls[spec->nb_syscalls++] = odp;
+ }
+
+ spec->nb_syscalls = sort_func_list( spec->syscalls, spec->nb_syscalls, link_name_compare );
+ if (!spec->nb_syscalls)
+ {
+ free( spec->syscalls );
+ spec->syscalls = NULL;
+ }
+}
+
+
/*******************************************************************
* add_16bit_exports
*
@@ -912,6 +969,8 @@ int parse_spec_file( FILE *file, DLLSPEC *spec )
current_line = 0; /* no longer parsing the input file */
assign_names( spec );
assign_ordinals( spec );
+ assign_syscalls( spec );
+
return !nb_errors;
}
diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c
index a52c03aaa6a..15ef9a3f893 100644
--- a/tools/winebuild/spec16.c
+++ b/tools/winebuild/spec16.c
@@ -495,27 +495,6 @@ static int relay_type_compare( const void *e1, const void *e2 )
}
-/*******************************************************************
- * sort_func_list
- *
- * Sort a list of functions, removing duplicates.
- */
-static int sort_func_list( ORDDEF **list, int count,
- int (*compare)(const void *, const void *) )
-{
- int i, j;
-
- if (!count) return 0;
- qsort( list, count, sizeof(*list), compare );
-
- for (i = j = 0; i < count; i++)
- {
- if (compare( &list[j], &list[i] )) list[++j] = list[i];
- }
- return j + 1;
-}
-
-
/*******************************************************************
* output_module16
*
@@ -544,6 +523,7 @@ static void output_module16( DLLSPEC *spec )
entry_point->flags = FLAG_REGISTER;
entry_point->name = NULL;
entry_point->link_name = xstrdup( spec->init_func );
+ entry_point->impl_name = NULL;
entry_point->export_name = NULL;
entry_point->u.func.nb_args = 0;
assert( !spec->ordinals[0] );
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c
index b1e20e0484d..22dd399cb2b 100644
--- a/tools/winebuild/spec32.c
+++ b/tools/winebuild/spec32.c
@@ -374,6 +374,109 @@ static void output_relay_debug( DLLSPEC *spec )
}
}
+/*******************************************************************
+ * output_syscall_thunks
+ *
+ * Output entry points for system call functions
+ */
+static void output_syscall_thunks( DLLSPEC *spec )
+{
+ int i;
+
+ if (!spec->nb_syscalls)
+ return;
+
+ output( "\n/* syscall thunks */\n\n" );
+ output( "\t.text\n" );
+
+ for (i = 0; i < spec->nb_syscalls; i++)
+ {
+ ORDDEF *odp = spec->syscalls[i];
+ const char *name = odp->link_name;
+
+ /* Chromium attempts to hook system call thunks. It expects them to
+ * have a very specific form, or it will fail. The below matches what
+ * Chromium expects from 64-bit Windows 8. */
+
+ output( "\t.balign 16, 0\n" );
+ output( "\t%s\n", func_declaration(name) );
+ output( "%s\n", asm_globl(name) );
+ output_cfi( ".cfi_startproc" );
+ output( "\t.byte 0xb8\n" ); /* mov eax, SYSCALL */
+ output( "\t.long %d\n", i );
+ output( "\t.byte 0x64,0xff,0x15,0xc0,0x00,0x00,0x00\n" ); /* call dword ptr fs:[0C0h] */
+ output( "\t.byte 0xc2\n" ); /* ret X */
+ output( "\t.short %d\n", get_args_size(odp) );
+ output_cfi( ".cfi_endproc" );
+ output_function_size( name );
+ }
+
+ for (i = 0; i < 0x20; i++)
+ output( "\t.byte 0\n" );
+
+ output( "\n/* syscall table */\n\n" );
+ output( "\t.data\n" );
+ output( "%s\n", asm_globl("__wine_syscall_table") );
+ for (i = 0; i < spec->nb_syscalls; i++)
+ {
+ ORDDEF *odp = spec->syscalls[i];
+ output ("\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->impl_name) );
+ }
+
+ output( "\n/* syscall argument stack size table */\n\n" );
+ output( "\t.data\n" );
+ output( "%s\n", asm_globl("__wine_syscall_stack_size") );
+ for (i = 0; i < spec->nb_syscalls; i++)
+ {
+ ORDDEF *odp = spec->syscalls[i];
+ output( "\t.byte %d\n", get_args_size(odp) );
+ }
+
+ output( "\n/* syscall dispatcher */\n\n" );
+ output( "\t.text\n" );
+ output( "\t.align %d\n", get_alignment(16) );
+ output( "\t%s\n", func_declaration("__wine_syscall_dispatcher") );
+ output( "%s\n", asm_globl("__wine_syscall_dispatcher") );
+ output_cfi( ".cfi_startproc" );
+ output( "\tpushl %%ebp\n" );
+ output_cfi( ".cfi_adjust_cfa_offset 4\n" );
+ output_cfi( ".cfi_rel_offset %%ebp,0\n" );
+ output( "\tmovl %%esp,%%ebp\n" );
+ output_cfi( ".cfi_def_cfa_register %%ebp\n" );
+ output( "\tpushl %%esi\n" );
+ output_cfi( ".cfi_rel_offset %%esi,-4\n" );
+ output( "\tpushl %%edi\n" );
+ output_cfi( ".cfi_rel_offset %%edi,-8\n" );
+ output( "\tleal 12(%%ebp),%%esi\n" );
+ if (UsePIC)
+ {
+ output( "\tcall 1f\n" );
+ output( "1:\tpopl %%edx\n" );
+ output( "movzbl (%s-1b)(%%edx,%%eax,1),%%ecx\n", asm_name("__wine_syscall_stack_size") );
+ }
+ else
+ output( "movzbl %s(%%eax),%%ecx\n", asm_name("__wine_syscall_stack_size") );
+
+ output( "\tsubl %%ecx,%%esp\n" );
+ output( "\tshrl $2,%%ecx\n" );
+ output( "\tmovl %%esp,%%edi\n" );
+ output( "\trep; movsl\n" );
+ if (UsePIC)
+ output( "\tcall *(%s-1b)(%%edx,%%eax,%d)\n", asm_name("__wine_syscall_table"), get_ptr_size() );
+ else
+ output( "\tcall *%s(,%%eax,%d)\n", asm_name("__wine_syscall_table"), get_ptr_size() );
+ output( "\tpop %%edi\n" );
+ output_cfi( ".cfi_same_value %%edi\n" );
+ output( "\tpop %%esi\n" );
+ output_cfi( ".cfi_same_value %%esi\n" );
+ output( "\tleave\n" );
+ output_cfi( ".cfi_def_cfa %%esp,4\n" );
+ output_cfi( ".cfi_same_value %%ebp\n" );
+ output( "\tret\n" );
+ output_cfi( ".cfi_endproc" );
+ output_function_size( "__wine_syscall_dispatcher" );
+}
+
/*******************************************************************
* output_exports
*
@@ -729,6 +832,7 @@ void output_spec32_file( DLLSPEC *spec )
open_output_file();
output_standard_file_header();
output_module( spec );
+ output_syscall_thunks( spec );
output_stubs( spec );
output_exports( spec );
output_imports( spec );
diff --git a/tools/winebuild/utils.c b/tools/winebuild/utils.c
index 2a1fc960926..07a579004ad 100644
--- a/tools/winebuild/utils.c
+++ b/tools/winebuild/utils.c
@@ -860,6 +860,7 @@ void free_dll_spec( DLLSPEC *spec )
free( odp->name );
free( odp->export_name );
free( odp->link_name );
+ free( odp->impl_name );
}
free( spec->file_name );
free( spec->dll_name );
@@ -869,6 +870,7 @@ void free_dll_spec( DLLSPEC *spec )
free( spec->names );
free( spec->ordinals );
free( spec->resources );
+ free( spec->syscalls );
free( spec );
}
@@ -1275,3 +1277,22 @@ const char *get_asm_string_section(void)
default: return ".section .rodata";
}
}
+
+/*******************************************************************
+ * sort_func_list
+ *
+ * Sort a list of functions, removing duplicates.
+ */
+int sort_func_list( ORDDEF **list, int count, int (*compare)(const void *, const void *) )
+{
+ int i, j;
+
+ if (!count) return 0;
+ qsort( list, count, sizeof(*list), compare );
+
+ for (i = j = 0; i < count; i++)
+ {
+ if (compare( &list[j], &list[i] )) list[++j] = list[i];
+ }
+ return j + 1;
+}
--
2.27.0

View File

@ -1,501 +0,0 @@
From 8650aa0a3229b84a102cca1d9fe40f9dbd5a038d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 7 Sep 2017 00:38:09 +0200
Subject: [PATCH] tools/winebuild: Add syscall thunks for 64 bit.
---
dlls/kernel32/tests/loader.c | 7 +-
dlls/ntdll/unix/thread.c | 2 +-
dlls/ntdll/unix/unix_private.h | 2 +-
dlls/ntdll/unix/virtual.c | 11 +-
libs/wine/loader.c | 4 +
server/mapping.c | 6 +-
tools/winebuild/parser.c | 2 +-
tools/winebuild/spec32.c | 285 ++++++++++++++++++++++++++++++++-
8 files changed, 305 insertions(+), 14 deletions(-)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index d39ebe4a37c..dccd9c1fc68 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -1571,7 +1571,7 @@ static void test_filenames(void)
static void test_FakeDLL(void)
{
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
NTSTATUS (WINAPI *pNtSetEvent)(HANDLE, ULONG *) = NULL;
IMAGE_EXPORT_DIRECTORY *dir;
HMODULE module = GetModuleHandleA("ntdll.dll");
@@ -1613,8 +1613,13 @@ static void test_FakeDLL(void)
dll_func = (BYTE *)GetProcAddress(module, func_name);
ok(dll_func != NULL, "%s: GetProcAddress returned NULL\n", func_name);
+#if defined(__i386__)
if (dll_func[0] == 0x90 && dll_func[1] == 0x90 &&
dll_func[2] == 0x90 && dll_func[3] == 0x90)
+#elif defined(__x86_64__)
+ if (dll_func[0] == 0x48 && dll_func[1] == 0x83 &&
+ dll_func[2] == 0xec && dll_func[3] == 0x08)
+#endif
{
todo_wine ok(0, "%s: Export is a stub-function, skipping\n", func_name);
continue;
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index 7952497645e..ca5eba4da88 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -104,7 +104,7 @@ TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZ
dbg_init();
server_init_process();
info_size = server_init_thread( teb->Peb, &suspend );
- virtual_map_user_shared_data();
+ virtual_map_user_shared_data( syscall_handler );
virtual_create_builtin_view( ntdll_module );
init_cpu_info();
init_files();
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 72987a0041b..15be5d3715a 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -187,7 +187,7 @@ extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_alloc_teb( TEB **ret_teb ) DECLSPEC_HIDDEN;
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_clear_tls_index( ULONG index ) DECLSPEC_HIDDEN;
-extern void virtual_map_user_shared_data(void) DECLSPEC_HIDDEN;
+extern void virtual_map_user_shared_data( void *syscall_handler ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) DECLSPEC_HIDDEN;
extern unsigned int virtual_locked_server_call( void *req_ptr ) DECLSPEC_HIDDEN;
extern ssize_t virtual_locked_read( int fd, void *addr, size_t size ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index e759cf686bd..0c8de5f2c24 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2608,14 +2608,14 @@ TEB *virtual_alloc_first_teb(void)
TEB *teb;
PEB *peb;
NTSTATUS status;
- SIZE_T data_size = page_size;
+ SIZE_T data_size = page_size * 2;
SIZE_T peb_size = page_size;
SIZE_T teb_size = signal_stack_mask + 1;
SIZE_T total = 32 * teb_size;
/* reserve space for shared user data */
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&user_shared_data, 0, &data_size,
- MEM_RESERVE | MEM_COMMIT, PAGE_READONLY );
+ MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
if (status)
{
ERR( "wine: failed to map the shared user data: %08x\n", status );
@@ -2839,7 +2839,7 @@ void virtual_clear_thread_stack( void *stack_end )
/***********************************************************************
* virtual_map_user_shared_data
*/
-void virtual_map_user_shared_data(void)
+void virtual_map_user_shared_data(void *syscall_handler)
{
static const WCHAR wine_usdW[] = {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
'\\','_','_','w','i','n','e','_','u','s','e','r','_','s','h','a','r','e','d','_','d','a','t','a',0};
@@ -2862,6 +2862,11 @@ void virtual_map_user_shared_data(void)
ERR( "failed to remap the process USD: %d\n", res );
exit(1);
}
+
+#if defined(__APPLE__) && defined(__x86_64__)
+ *((void **)((char*)user_shared_data + 0x1000)) = syscall_handler;
+#endif
+
if (needs_close) close( fd );
NtClose( section );
}
diff --git a/libs/wine/loader.c b/libs/wine/loader.c
index 4597a6cb324..3d0d75e9c6d 100644
--- a/libs/wine/loader.c
+++ b/libs/wine/loader.c
@@ -398,7 +398,11 @@ static void *map_dll( const IMAGE_NT_HEADERS *nt_descr )
sec->SizeOfRawData = code_end - code_start;
sec->Misc.VirtualSize = sec->SizeOfRawData;
sec->VirtualAddress = code_start;
+#ifdef _WIN64
+ sec->PointerToRawData = 0x400; /* file alignment */
+#else
sec->PointerToRawData = 0x200; /* file alignment */
+#endif
sec->Characteristics = (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ);
sec++;
diff --git a/server/mapping.c b/server/mapping.c
index 0941dd87c05..002f3215af2 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -964,7 +964,11 @@ struct object *create_user_data_mapping( struct object *root, const struct unico
if (!(mapping = create_mapping( root, name, OBJ_OPENIF, sizeof(KSHARED_USER_DATA),
SEC_COMMIT, 0, FILE_READ_DATA | FILE_WRITE_DATA, NULL ))) return NULL;
ptr = mmap( NULL, mapping->size, PROT_WRITE, MAP_SHARED, get_unix_fd( mapping->fd ), 0 );
- if (ptr != MAP_FAILED) user_shared_data = ptr;
+ if (ptr != MAP_FAILED)
+ {
+ user_shared_data = ptr;
+ user_shared_data->SystemCallPad[0] = 1;
+ }
return &mapping->obj;
}
diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c
index 91f596f1d2d..533ec5d2009 100644
--- a/tools/winebuild/parser.c
+++ b/tools/winebuild/parser.c
@@ -545,7 +545,7 @@ static const char *parse_spec_flags( DLLSPEC *spec, ORDDEF *odp )
static int needs_syscall( ORDDEF *odp, DLLSPEC *spec )
{
- if (target_cpu != CPU_x86)
+ if (target_cpu != CPU_x86 && target_cpu != CPU_x86_64)
return 0;
if (odp->flags & (FLAG_FORWARD | FLAG_REGISTER))
return 0;
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c
index 07d6eed05fc..9cc4698d0d7 100644
--- a/tools/winebuild/spec32.c
+++ b/tools/winebuild/spec32.c
@@ -375,11 +375,11 @@ static void output_relay_debug( DLLSPEC *spec )
}
/*******************************************************************
- * output_syscall_thunks
+ * output_syscall_thunks_x86
*
* Output entry points for system call functions
*/
-static void output_syscall_thunks( DLLSPEC *spec )
+static void output_syscall_thunks_x86( DLLSPEC *spec )
{
const unsigned int page_size = get_page_size();
int i;
@@ -488,6 +488,157 @@ static void output_syscall_thunks( DLLSPEC *spec )
output_function_size( "__wine_syscall_dispatcher" );
}
+/*******************************************************************
+ * output_syscall_thunks_x64
+ *
+ * Output entry points for system call functions
+ */
+static void output_syscall_thunks_x64( DLLSPEC *spec )
+{
+ const unsigned int page_size = get_page_size();
+ int i;
+
+ if (!spec->nb_syscalls)
+ return;
+
+ /* Reserve space for PE header directly before syscalls. */
+ if (target_platform == PLATFORM_APPLE)
+ output( "\t.text\n" );
+ else
+ output( "\n\t.section \".text.startup\"\n" );
+
+ output( "\t.align %d\n", get_alignment(65536) );
+ output( "__wine_spec_pe_header_syscalls:\n" );
+ output( "__wine_spec_pe_header_syscalls_end:\n" );
+ output( "\t.byte 0\n" );
+ output( "\t.balign %d, 0\n", page_size );
+
+ output( "\n/* syscall thunks */\n\n" );
+ for (i = 0; i < spec->nb_syscalls; i++)
+ {
+ ORDDEF *odp = spec->syscalls[i];
+ const char *name = odp->link_name;
+
+ /* Chromium depends on syscall thunks having the same form as on
+ * Windows. For 64-bit systems the only viable form we can emulate is
+ * having an int $0x2e fallback. Since actually using an interrupt is
+ * expensive, and since for some reason Chromium doesn't actually
+ * validate that instruction, we can just put a jmp there instead. */
+
+ output( "\t.balign 16, 0\n" );
+ output( "\t%s\n", func_declaration(name) );
+ output( "%s\n", asm_globl(name) );
+ output_cfi( ".cfi_startproc" );
+ output( "\t.byte 0x4c,0x8b,0xd1\n" ); /* mov r10, rcx */
+ output( "\t.byte 0xb8\n" ); /* mov eax, SYSCALL */
+ output( "\t.long %d\n", i );
+ output( "\t.byte 0xf6,0x04,0x25,0x08,0x03,0xfe,0x7f,0x01\n" ); /* test byte ptr [0x7ffe0308], 1 */
+ output( "\t.byte 0x75,0x03\n" ); /* jne (over syscall) */
+ output( "\t.byte 0x0f,0x05\n" ); /* syscall */
+ output( "\t.byte 0xc3\n" ); /* ret */
+ output( "\t.byte 0xeb,0x01\n" ); /* jmp over ret */
+ output( "\t.byte 0xc3\n" ); /* ret */
+ if (target_platform == PLATFORM_APPLE)
+ {
+ output( "\t.byte 0xff,0x14,0x25\n" ); /* call [0x7ffe1000] */
+ output( "\t.long 0x7ffe1000\n" );
+ }
+ else
+ {
+ output( "\t.byte 0x65,0xff,0x14,0x25\n" ); /* call qword ptr gs:[0x100] */
+ output( "\t.long 0x100\n");
+ }
+ /* This RET is never reached, but Legends of Runeterra demands that it
+ * exist anyway. */
+ output( "\t.byte 0xc3\n" ); /* ret */
+ output_cfi( ".cfi_endproc" );
+ output_function_size( name );
+ }
+
+ for (i = 0; i < 0x20; i++)
+ output( "\t.byte 0\n" );
+
+ output( "\n/* syscall table */\n\n" );
+ output( "\t.data\n" );
+ output( "%s\n", asm_globl("__wine_syscall_table") );
+ for (i = 0; i < spec->nb_syscalls; i++)
+ {
+ ORDDEF *odp = spec->syscalls[i];
+ output ("\t%s %s\n", get_asm_ptr_keyword(), asm_name(odp->impl_name) );
+ }
+
+ output( "\n/* syscall argument stack size table */\n\n" );
+ output( "\t.data\n" );
+ output( "%s\n", asm_globl("__wine_syscall_stack_size") );
+ for (i = 0; i < spec->nb_syscalls; i++)
+ {
+ ORDDEF *odp = spec->syscalls[i];
+ output( "\t.byte %d\n", max(get_args_size(odp), 32) - 32 );
+ }
+
+ output( "\n/* syscall dispatcher */\n\n" );
+ output( "\t.text\n" );
+ output( "\t.align %d\n", get_alignment(16) );
+ output( "\t%s\n", func_declaration("__wine_syscall_dispatcher") );
+ output( "%s\n", asm_globl("__wine_syscall_dispatcher") );
+
+ /* prologue */
+ output_cfi( ".cfi_startproc" );
+ output( "\tpushq %%rbp\n" );
+ output_cfi( ".cfi_adjust_cfa_offset 8" );
+ output_cfi( ".cfi_rel_offset %%rbp,0" );
+ output( "\tmovq %%rsp,%%rbp\n" );
+ output_cfi( ".cfi_def_cfa_register %%rbp" );
+ output( "\tpushq %%rsi\n" );
+ output_cfi( ".cfi_rel_offset %%rsi,-8" );
+ output( "\tpushq %%rdi\n" );
+ output_cfi( ".cfi_rel_offset %%rdi,-16" );
+
+ /* Legends of Runeterra hooks the first system call return instruction, and
+ * depends on us returning to it. Adjust the return address accordingly. */
+ if (target_platform == PLATFORM_APPLE)
+ output( "\tsubq $0xb,0x8(%%rbp)\n" );
+ else
+ output( "\tsubq $0xc,0x8(%%rbp)\n" );
+
+ /* copy over any arguments on the stack */
+ output( "\tleaq 0x38(%%rbp),%%rsi\n" );
+ if (UsePIC)
+ {
+ output( "\tleaq (%%rip), %%r11\n" );
+ output( "1:\tmovzbq (%s-1b)(%%r11,%%rax,1),%%rcx\n", asm_name("__wine_syscall_stack_size") );
+ }
+ else
+ output( "\tmovzbq %s(%%rax),%%rcx\n", asm_name("__wine_syscall_stack_size") );
+ output( "\tsubq %%rcx,%%rsp\n" );
+ output( "\tand $~0xf,%%rsp\n\t" ); /* ensure stack alignment. */
+ output( "\tshrq $3,%%rcx\n" );
+ output( "\tmovq %%rsp,%%rdi\n" );
+ output( "\trep; movsq\n" );
+
+ /* call the function */
+ output( "\tmovq %%r10,%%rcx\n" );
+ output( "\tsubq $0x20,%%rsp\n" );
+ if (UsePIC)
+ output( "\tcallq *(%s-1b)(%%r11,%%rax,%d)\n", asm_name("__wine_syscall_table"), get_ptr_size() );
+ else
+ output( "\tcallq *%s(,%%rax,%d)\n", asm_name("__wine_syscall_table"), get_ptr_size() );
+ output( "\tleaq -0x10(%%rbp),%%rsp\n" );
+
+ /* epilogue */
+ output( "\tpopq %%rdi\n" );
+ output_cfi( ".cfi_same_value %%rdi" );
+ output( "\tpopq %%rsi\n" );
+ output_cfi( ".cfi_same_value %%rsi" );
+ output_cfi( ".cfi_def_cfa_register %%rsp" );
+ output( "\tpopq %%rbp\n" );
+ output_cfi( ".cfi_adjust_cfa_offset -8" );
+ output_cfi( ".cfi_same_value %%rbp" );
+ output( "\tret\n" );
+ output_cfi( ".cfi_endproc" );
+ output_function_size( "__wine_syscall_dispatcher" );
+}
+
/*******************************************************************
* output_exports
*
@@ -845,7 +996,10 @@ void output_spec32_file( DLLSPEC *spec )
open_output_file();
output_standard_file_header();
output_module( spec );
- output_syscall_thunks( spec );
+ if (target_cpu == CPU_x86)
+ output_syscall_thunks_x86( spec );
+ else if (target_cpu == CPU_x86_64)
+ output_syscall_thunks_x64( spec );
output_stubs( spec );
output_exports( spec );
output_imports( spec );
@@ -858,7 +1012,7 @@ void output_spec32_file( DLLSPEC *spec )
static int needs_stub_exports( DLLSPEC *spec )
{
- if (target_cpu != CPU_x86)
+ if (target_cpu != CPU_x86 && target_cpu != CPU_x86_64)
return 0;
if (!(spec->characteristics & IMAGE_FILE_DLL))
return 0;
@@ -868,7 +1022,7 @@ static int needs_stub_exports( DLLSPEC *spec )
}
-static void create_stub_exports_text( DLLSPEC *spec )
+static void create_stub_exports_text_x86( DLLSPEC *spec )
{
int i, nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
size_t rva, thunk;
@@ -1026,6 +1180,122 @@ static void create_stub_exports_text( DLLSPEC *spec )
}
+static void create_stub_exports_text_x64( DLLSPEC *spec )
+{
+ int i, nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0;
+
+ /* output syscalls */
+ for (i = 0; i < spec->nb_syscalls; i++)
+ {
+ ORDDEF *odp = spec->syscalls[i];
+
+ align_output_rva( 16, 16 );
+ put_label( odp->link_name );
+ put_byte( 0x4c ); put_byte( 0x8b ); put_byte( 0xd1 ); /* mov r10, rcx */
+ put_byte( 0xb8 ); put_dword( i ); /* mov eax, SYSCALL */
+ put_byte( 0xf6 ); put_byte( 0x04 ); put_byte( 0x25 ); /* test byte ptr [0x7ffe0308], 1 */
+ put_byte( 0x08 ); put_byte( 0x03 ); put_byte( 0xfe );
+ put_byte( 0x7f ); put_byte( 0x01 );
+ put_byte( 0x75 ); put_byte( 0x03 ); /* jne */
+ put_byte( 0x0f ); put_byte( 0x05 ); /* syscall */
+ put_byte( 0xc3 ); /* ret */
+ put_byte( 0xeb ); put_byte( 0x01 ); /* jmp */
+ put_byte( 0xc3 ); /* ret */
+ if (target_platform == PLATFORM_APPLE)
+ {
+ put_byte( 0xff ); put_byte( 0x14 ); /* call [0x7ffe1000] */
+ put_byte( 0x25 ); put_dword( 0x7ffe1000 );
+ }
+ else
+ {
+ put_byte( 0x65 ); put_byte( 0xff ); /* call ptr gs:[0x100] */
+ put_byte( 0x14 ); put_byte( 0x25 ); put_dword( 0x100 );
+
+ }
+ put_byte( 0xc3 ); /* ret */
+ }
+
+ if (spec->nb_syscalls)
+ {
+ for (i = 0; i < 0x20; i++)
+ put_byte( 0 );
+ }
+
+ /* output stub code for exports */
+ for (i = 0; i < spec->nb_entry_points; i++)
+ {
+ ORDDEF *odp = &spec->entry_points[i];
+ const char *name;
+
+ if (odp->flags & FLAG_SYSCALL)
+ continue;
+
+ align_output_rva( 16, 16 );
+ name = get_stub_name( odp, spec );
+ put_label( name );
+ put_byte( 0xcc ); /* int $0x3 */
+ put_byte( 0xc3 ); /* ret */
+ }
+
+ /* output entry point */
+ align_output_rva( 16, 16 );
+ put_label( "entrypoint" );
+ put_byte( 0xb8 ); put_dword( 1 ); /* mov rax, 1 */
+ put_byte( 0xc3 ); /* ret */
+
+ /* export directory */
+ align_output_rva( 16, 16 );
+ put_label( "export_start" );
+ put_dword( 0 ); /* Characteristics */
+ put_dword( 0 ); /* TimeDateStamp */
+ put_dword( 0 ); /* MajorVersion/MinorVersion */
+ put_dword( label_rva("dll_name") ); /* Name */
+ put_dword( spec->base ); /* Base */
+ put_dword( nr_exports ); /* NumberOfFunctions */
+ put_dword( spec->nb_names ); /* NumberOfNames */
+ put_dword( label_rva("export_funcs") ); /* AddressOfFunctions */
+ put_dword( label_rva("export_names") ); /* AddressOfNames */
+ put_dword( label_rva("export_ordinals") ); /* AddressOfNameOrdinals */
+
+ put_label( "export_funcs" );
+ for (i = spec->base; i <= spec->limit; i++)
+ {
+ ORDDEF *odp = spec->ordinals[i];
+ if (odp)
+ {
+ const char *name = (odp->flags & FLAG_SYSCALL) ? odp->link_name : get_stub_name( odp, spec );
+ put_dword( label_rva( name ) );
+ }
+ else
+ put_dword( 0 );
+ }
+
+ if (spec->nb_names)
+ {
+ put_label( "export_names" );
+ for (i = 0; i < spec->nb_names; i++)
+ put_dword( label_rva(strmake("str_%s", get_stub_name(spec->names[i], spec))) );
+
+ put_label( "export_ordinals" );
+ for (i = 0; i < spec->nb_names; i++)
+ put_word( spec->names[i]->ordinal - spec->base );
+ if (spec->nb_names % 2)
+ put_word( 0 );
+ }
+
+ put_label( "dll_name" );
+ put_str( spec->file_name );
+
+ for (i = 0; i < spec->nb_names; i++)
+ {
+ put_label( strmake("str_%s", get_stub_name(spec->names[i], spec)) );
+ put_str( spec->names[i]->name );
+ }
+
+ put_label( "export_end" );
+}
+
+
static void create_stub_exports_data( DLLSPEC *spec )
{
int i;
@@ -1225,7 +1495,10 @@ static void output_fake_module_pass( DLLSPEC *spec )
if (needs_stub_exports( spec ))
{
put_label( "text_start" );
- create_stub_exports_text( spec );
+ if (target_cpu == CPU_x86)
+ create_stub_exports_text_x86( spec );
+ else if (target_cpu == CPU_x86_64)
+ create_stub_exports_text_x64( spec );
put_label( "text_end" );
}
else
--
2.27.0

View File

@ -1,18 +0,0 @@
Fixes: [21232] Chromium-based browser engines (Chrome, Opera, Comodo Dragon, SRWare Iron) crash on startup unless '--no-sandbox' is used (native API sandboxing/hooking scheme incompatible with Wine)
Fixes: [42741] StarCraft I: 1.18 PTR fails to initialize ClientSdk.dll
Fixes: [45349] Multiple applications and games crash due to missing support for 64-bit syscall thunks (StreetFighter V)
Fixes: [45573] League of Legends 8.12+ fails to start a game (anticheat engine, hooking of syscall return instructions)
Fixes: [45650] chromium 32-bit sandbox expects different syscall thunks depending on Windows version
Depends: ntdll-WRITECOPY
Depends: ws2_32-WSACleanup
Depends: ntdll-ApiSetMap
# As of 43be3507c04, unless I've misread, ntdll.dll no longer has the chance to
# run code before ntdll.so performs process initialization. Unfortunately,
# ntdll.so is still making calls to Nt* exports during that process
# initialization, which in practice means it's calling syscall thunks. In order
# for this series to work, we need to poke __wine_syscall_dispatcher into the
# TEB before those calls are made. Fixing this would require a nontrivial amount
# of effort, which will be obviated as soon as Alexandre finishes splitting
# ntdll upstream.
Disabled: true

View File

@ -1,4 +1,4 @@
From 3f245724b06ff75421810f5069beadc6b7610f52 Mon Sep 17 00:00:00 2001
From da32913e84869282c7e78c09f6b15cb71c4fb255 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <jkucia@codeweavers.com>
Date: Wed, 24 Jun 2020 17:31:03 -0600
Subject: [PATCH] winevulkan: Avoid returning 0 for swapchain maxImageCount.
@ -14,7 +14,7 @@ AMDVLK also sets this to 16 when no maxImageCount is specified.
4 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index a0bf6b0859e..c28abe8ebb4 100755
index b84eb39587e..59df1dbf407 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -183,7 +183,7 @@ FUNCTION_OVERRIDES = {
@ -27,11 +27,11 @@ index a0bf6b0859e..c28abe8ebb4 100755
"vkGetPhysicalDeviceSurfacePresentModesKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index eb22e72ae36..543388abe8e 100644
index 4642975ad0f..abb9e0a9063 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -1358,6 +1358,25 @@ void WINAPI wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDev
properties->externalSemaphoreFeatures = 0;
@@ -1409,6 +1409,25 @@ void WINAPI wine_vkGetPrivateDataEXT(VkDevice device, VkObjectType object_type,
device->funcs.p_vkGetPrivateDataEXT(device->device, object_type, object_handle, private_data_slot, data);
}
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice phys_dev,
@ -57,7 +57,7 @@ index eb22e72ae36..543388abe8e 100644
{
TRACE("%p, %u, %p\n", hinst, reason, reserved);
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index f8d171a6db3..3dcbd824a30 100644
index 94aa1e3fb7b..d5b39851eaf 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -4956,9 +4956,8 @@ static VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysica
@ -72,7 +72,7 @@ index f8d171a6db3..3dcbd824a30 100644
}
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index 9580c6bbcd2..18e3ce5fe1c 100644
index 7055d4fb135..f0f0ae787b5 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -40,6 +40,7 @@ VkResult WINAPI wine_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice
@ -80,10 +80,10 @@ index 9580c6bbcd2..18e3ce5fe1c 100644
void WINAPI wine_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties);
void WINAPI wine_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities);
void WINAPI wine_vkGetPrivateDataEXT(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t *pData) DECLSPEC_HIDDEN;
VkResult WINAPI wine_vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence);
/* Private thunks */
@@ -47,6 +48,7 @@ VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physic
VkResult WINAPI wine_vkSetPrivateDataEXT(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t data) DECLSPEC_HIDDEN;
@@ -49,6 +50,7 @@ VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physic
VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
void thunk_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;
void thunk_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;

View File

@ -1 +1 @@
e0e3b6bc91f7db956e3a66f2938eea45d4055a39
262e4ab9e0eeb126dde5cb4cba13fbf7f1d1cef0