ntdll: Store the filesystem redirection flag in the 64-bit TEB.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a865a4f61d
commit
d18b566995
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -686,6 +686,9 @@ typedef struct _TEB64
|
|||
GUID EffectiveContainerId; /* 1828 */
|
||||
} TEB64;
|
||||
|
||||
/* reserved TEB64 TLS slots for Wow64 */
|
||||
#define WOW64_TLS_FILESYSREDIR 8
|
||||
|
||||
#endif /* _WIN64 */
|
||||
|
||||
/***********************************************************************
|
||||
|
|
Loading…
Reference in New Issue