ntdll: Store the filesystem redirection flag in the 64-bit TEB.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-24 13:29:31 +02:00
parent a865a4f61d
commit d18b566995
9 changed files with 50 additions and 35 deletions

View File

@ -104,9 +104,13 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, char *nam
*/
NTSTATUS WINAPI RtlWow64EnableFsRedirection( BOOLEAN enable )
{
if (!is_wow64) return STATUS_NOT_IMPLEMENTED;
ntdll_get_thread_data()->wow64_redir = enable;
#ifdef _WIN64
return STATUS_NOT_IMPLEMENTED;
#else
if (!NtCurrentTeb64()) return STATUS_NOT_IMPLEMENTED;
NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR] = !enable;
return STATUS_SUCCESS;
#endif
}
@ -115,11 +119,14 @@ NTSTATUS WINAPI RtlWow64EnableFsRedirection( BOOLEAN enable )
*/
NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx( ULONG disable, ULONG *old_value )
{
if (!is_wow64) return STATUS_NOT_IMPLEMENTED;
#ifdef _WIN64
return STATUS_NOT_IMPLEMENTED;
#else
if (!NtCurrentTeb64()) return STATUS_NOT_IMPLEMENTED;
__TRY
{
*old_value = !ntdll_get_thread_data()->wow64_redir;
*old_value = NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR];
}
__EXCEPT_PAGE_FAULT
{
@ -127,8 +134,9 @@ NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx( ULONG disable, ULONG *old_value )
}
__ENDTRY
ntdll_get_thread_data()->wow64_redir = !disable;
NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR] = disable;
return STATUS_SUCCESS;
#endif
}

View File

@ -110,25 +110,6 @@ enum loadorder
extern enum loadorder get_load_order( const WCHAR *app_name, const UNICODE_STRING *nt_name ) DECLSPEC_HIDDEN;
/* thread private data, stored in NtCurrentTeb()->GdiTebBatch */
struct ntdll_thread_data
{
void *cpu_data[16]; /* reserved for CPU-specific data */
struct debug_info *debug_info; /* info for debugstr functions */
void *start_stack; /* stack for thread startup */
int request_fd; /* fd for sending server requests */
int reply_fd; /* fd for receiving server replies */
int wait_fd[2]; /* fd for sleeping server requests */
BOOL wow64_redir; /* Wow64 filesystem redirection flag */
};
C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) );
static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
{
return (struct ntdll_thread_data *)&NtCurrentTeb()->GdiTebBatch;
}
#ifndef _WIN64
static inline TEB64 *NtCurrentTeb64(void) { return (TEB64 *)NtCurrentTeb()->GdiBatchCount; }
#endif

View File

@ -75,16 +75,15 @@ struct x86_thread_data
DWORD dr6; /* 1ec */
DWORD dr7; /* 1f0 */
void *exit_frame; /* 1f4 exit frame pointer */
/* the ntdll_thread_data structure follows here */
};
C_ASSERT( sizeof(struct x86_thread_data) <= sizeof( ((struct ntdll_thread_data *)0)->cpu_data ));
C_ASSERT( sizeof(struct x86_thread_data) <= 16 * sizeof(void *) );
C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, gs ) == 0x1d8 );
C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, exit_frame ) == 0x1f4 );
static inline struct x86_thread_data *x86_thread_data(void)
{
return (struct x86_thread_data *)ntdll_get_thread_data()->cpu_data;
return (struct x86_thread_data *)&NtCurrentTeb()->GdiTebBatch;
}
struct ldt_copy *__wine_ldt_copy = NULL;

View File

@ -845,6 +845,7 @@ static void test_redirection(void)
{
ULONG old, cur;
NTSTATUS status;
ULONGLONG *tls64 = NULL;
if (!pRtlWow64EnableFsRedirection || !pRtlWow64EnableFsRedirectionEx)
{
@ -859,21 +860,39 @@ static void test_redirection(void)
}
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
#ifndef _WIN64
if (NtCurrentTeb()->GdiBatchCount)
tls64 = ((TEB64 *)NtCurrentTeb()->GdiBatchCount)->TlsSlots + WOW64_TLS_FILESYSREDIR;
#endif
status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( !cur, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
if (tls64) ok( *tls64 == FALSE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
if (tls64) ok( *tls64 == TRUE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirection( TRUE );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( !cur, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
if (tls64) ok( *tls64 == TRUE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirectionEx( 123, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( cur == TRUE, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
if (tls64) ok( *tls64 == 123, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirectionEx( 0xdeadbeef, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( cur == 123, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
if (tls64) ok( *tls64 == 0xdeadbeef, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirectionEx( TRUE, NULL );
ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status );
@ -887,6 +906,7 @@ static void test_redirection(void)
status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
if (tls64) ok( *tls64 == FALSE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
pRtlWow64EnableFsRedirectionEx( old, &cur );
}

View File

@ -2708,9 +2708,6 @@ static int get_redirect_path( char *unix_name, int pos, const WCHAR *name, int l
#else /* _WIN64 */
/* there are no redirects on 64-bit */
static const unsigned int nb_redirects = 0;
static int get_redirect_path( char *unix_name, int pos, const WCHAR *name, int length, BOOLEAN check_case )
{
return 0;
@ -3067,7 +3064,11 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
int ret, len;
struct stat st;
char *unix_name = *buffer;
const BOOL redirect = nb_redirects && ntdll_get_thread_data()->wow64_redir;
#ifdef _WIN64
const BOOL redirect = FALSE;
#else
const BOOL redirect = NtCurrentTeb64() && !NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR];
#endif
/* try a shortcut first */

View File

@ -277,7 +277,9 @@ static BOOL is_builtin_path( UNICODE_STRING *path, BOOL *is_64bit )
*is_64bit = is_win64;
if (path->Length > sizeof(systemW) && !wcsnicmp( path->Buffer, systemW, ARRAY_SIZE(systemW) ))
{
if (is_wow64 && !ntdll_get_thread_data()->wow64_redir) *is_64bit = TRUE;
#ifndef _WIN64
if (NtCurrentTeb64() && NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR]) *is_64bit = TRUE;
#endif
return TRUE;
}
if ((is_win64 || is_wow64) && path->Length > sizeof(wow64W) &&

View File

@ -1564,8 +1564,6 @@ size_t server_init_thread( void *entry_point, BOOL *suspend )
}
#endif
ntdll_get_thread_data()->wow64_redir = is_wow64;
switch (ret)
{
case STATUS_SUCCESS:

View File

@ -57,7 +57,6 @@ struct ntdll_thread_data
int request_fd; /* fd for sending server requests */
int reply_fd; /* fd for receiving server replies */
int wait_fd[2]; /* fd for sleeping server requests */
BOOL wow64_redir; /* Wow64 filesystem redirection flag */
pthread_t pthread_id; /* pthread thread id */
struct list entry; /* entry in TEB list */
PRTL_THREAD_START_ROUTINE start; /* thread entry point */
@ -288,6 +287,10 @@ static inline void *get_signal_stack(void)
return (char *)NtCurrentTeb() + teb_size - teb_offset;
}
#ifndef _WIN64
static inline TEB64 *NtCurrentTeb64(void) { return (TEB64 *)NtCurrentTeb()->GdiBatchCount; }
#endif
static inline size_t ntdll_wcslen( const WCHAR *str )
{
const WCHAR *s = str;

View File

@ -686,6 +686,9 @@ typedef struct _TEB64
GUID EffectiveContainerId; /* 1828 */
} TEB64;
/* reserved TEB64 TLS slots for Wow64 */
#define WOW64_TLS_FILESYSREDIR 8
#endif /* _WIN64 */
/***********************************************************************