Skip to content
Snippets Groups Projects
Commit 0a7c1f6c authored by Alexandre Julliard's avatar Alexandre Julliard
Browse files

Implemented GetThreadSelectorEntry through the server.

parent 3d678afc
No related branches found
No related tags found
No related merge requests found
......@@ -148,6 +148,8 @@ struct boot_done_request
/* Initialize a process; called from the new process context */
struct init_process_request
{
IN void* ldt_copy; /* addr of LDT copy */
IN void* ldt_flags; /* addr of LDT flags */
OUT int start_flags; /* flags from startup info */
OUT int hstdin; /* handle for stdin */
OUT int hstdout; /* handle for stdout */
......@@ -1031,6 +1033,17 @@ struct set_thread_context_request
};
/* Fetch a selector entry for a thread */
struct get_selector_entry_request
{
IN int handle; /* thread handle */
IN int entry; /* LDT entry */
OUT unsigned int base; /* selector base */
OUT unsigned int limit; /* selector limit */
OUT unsigned char flags; /* selector flags */
};
/* Everything below this line is generated automatically by tools/make_requests */
/* ### make_requests begin ### */
......@@ -1128,6 +1141,7 @@ enum request
REQ_CANCEL_TIMER,
REQ_GET_THREAD_CONTEXT,
REQ_SET_THREAD_CONTEXT,
REQ_GET_SELECTOR_ENTRY,
REQ_NB_REQUESTS
};
......
......@@ -5,16 +5,18 @@
*/
#include <string.h>
#include "winerror.h"
#include "wine/winbase16.h"
#include "ldt.h"
#include "miscemu.h"
#include "selectors.h"
#include "stackframe.h"
#include "process.h"
#include "server.h"
#include "debugtools.h"
#include "toolhelp.h"
DEFAULT_DEBUG_CHANNEL(selector)
DEFAULT_DEBUG_CHANNEL(selector);
/***********************************************************************
......@@ -604,28 +606,74 @@ void WINAPI UnMapLS( SEGPTR sptr )
/***********************************************************************
* GetThreadSelectorEntry (KERNEL32)
* FIXME: add #ifdef i386 for non x86
*/
BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel,
LPLDT_ENTRY ldtent)
{
ldt_entry ldtentry;
LDT_GetEntry(SELECTOR_TO_ENTRY(sel),&ldtentry);
ldtent->BaseLow = ldtentry.base & 0x0000ffff;
ldtent->HighWord.Bits.BaseMid = (ldtentry.base & 0x00ff0000) >> 16;
ldtent->HighWord.Bits.BaseHi = (ldtentry.base & 0xff000000) >> 24;
ldtent->LimitLow = ldtentry.limit & 0x0000ffff;
ldtent->HighWord.Bits.LimitHi = (ldtentry.limit & 0x00ff0000) >> 16;
ldtent->HighWord.Bits.Dpl = 3;
ldtent->HighWord.Bits.Sys = 0;
ldtent->HighWord.Bits.Pres = 1;
ldtent->HighWord.Bits.Type = 0x10|(ldtentry.type << 2);
if (!ldtentry.read_only)
ldtent->HighWord.Bits.Type|=0x2;
ldtent->HighWord.Bits.Granularity = ldtentry.limit_in_pages;
ldtent->HighWord.Bits.Default_Big = ldtentry.seg_32bit;
*/
BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldtent)
{
#ifdef __i386__
struct get_selector_entry_request *req = get_req_buffer();
if (!(sel & 4)) /* GDT selector */
{
WORD seg;
sel &= ~3; /* ignore RPL */
if (!sel) /* null selector */
{
memset( ldtent, 0, sizeof(*ldtent) );
return TRUE;
}
ldtent->BaseLow = 0;
ldtent->HighWord.Bits.BaseMid = 0;
ldtent->HighWord.Bits.BaseHi = 0;
ldtent->LimitLow = 0xffff;
ldtent->HighWord.Bits.LimitHi = 0xf;
ldtent->HighWord.Bits.Dpl = 3;
ldtent->HighWord.Bits.Sys = 0;
ldtent->HighWord.Bits.Pres = 1;
ldtent->HighWord.Bits.Granularity = 1;
ldtent->HighWord.Bits.Default_Big = 1;
ldtent->HighWord.Bits.Type = 0x12;
/* it has to be one of the system GDT selectors */
GET_DS(seg);
if (sel == (seg & ~3)) return TRUE;
GET_SS(seg);
if (sel == (seg & ~3)) return TRUE;
GET_CS(seg);
if (sel == (seg & ~3))
{
ldtent->HighWord.Bits.Type |= 8; /* code segment */
return TRUE;
}
SetLastError( ERROR_NOACCESS );
return FALSE;
}
req->handle = hthread;
req->entry = sel >> __AHSHIFT;
if (server_call( REQ_GET_SELECTOR_ENTRY )) return FALSE;
if (!(req->flags & LDT_FLAGS_ALLOCATED))
{
SetLastError( ERROR_MR_MID_NOT_FOUND ); /* sic */
return FALSE;
}
if (req->flags & LDT_FLAGS_BIG) req->limit >>= 12;
ldtent->BaseLow = req->base & 0x0000ffff;
ldtent->HighWord.Bits.BaseMid = (req->base & 0x00ff0000) >> 16;
ldtent->HighWord.Bits.BaseHi = (req->base & 0xff000000) >> 24;
ldtent->LimitLow = req->limit & 0x0000ffff;
ldtent->HighWord.Bits.LimitHi = (req->limit & 0x000f0000) >> 16;
ldtent->HighWord.Bits.Dpl = 3;
ldtent->HighWord.Bits.Sys = 0;
ldtent->HighWord.Bits.Pres = 1;
ldtent->HighWord.Bits.Granularity = (req->flags & LDT_FLAGS_BIG) !=0;
ldtent->HighWord.Bits.Default_Big = (req->flags & LDT_FLAGS_32BIT) != 0;
ldtent->HighWord.Bits.Type = ((req->flags & LDT_FLAGS_TYPE) << 2) | 0x10;
if (!(req->flags & LDT_FLAGS_READONLY)) ldtent->HighWord.Bits.Type |= 0x2;
return TRUE;
#else
SetLastError( ERROR_NOT_IMPLEMENTED );
return FALSE;
#endif
}
......
......@@ -254,6 +254,8 @@ static BOOL PROCESS_CreateEnvDB(void)
/* Retrieve startup info from the server */
req->ldt_copy = ldt_copy;
req->ldt_flags = ldt_flags_copy;
if (server_call( REQ_INIT_PROCESS )) return FALSE;
startup->dwFlags = req->start_flags;
startup->wShowWindow = req->cmd_show;
......
......@@ -149,6 +149,8 @@ struct thread *create_process( int fd, struct process *parent,
process->console_out = NULL;
process->init_event = NULL;
process->info = NULL;
process->ldt_copy = NULL;
process->ldt_flags = NULL;
gettimeofday( &process->start_time, NULL );
if ((process->next = first_process) != NULL) process->next->prev = process;
first_process = process;
......@@ -539,6 +541,8 @@ DECL_HANDLER(init_process)
fatal_protocol_error( current, "init_process: called twice\n" );
return;
}
current->process->ldt_copy = req->ldt_copy;
current->process->ldt_flags = req->ldt_flags;
current->process->info = NULL;
req->start_flags = info->start_flags;
req->hstdin = info->hstdin;
......
......@@ -34,6 +34,8 @@ struct process
struct object *console_in; /* console input */
struct object *console_out; /* console output */
struct event *init_event; /* event for init done */
void *ldt_copy; /* pointer to LDT copy in client addr space */
void *ldt_flags; /* pointer to LDT flags in client addr space */
struct new_process_request *info; /* startup info (freed after startup) */
};
......
......@@ -162,6 +162,7 @@ DECL_HANDLER(set_timer);
DECL_HANDLER(cancel_timer);
DECL_HANDLER(get_thread_context);
DECL_HANDLER(set_thread_context);
DECL_HANDLER(get_selector_entry);
#ifdef WANT_REQUEST_HANDLERS
......@@ -261,6 +262,7 @@ static const struct handler {
{ (void(*)())req_cancel_timer, sizeof(struct cancel_timer_request) },
{ (void(*)())req_get_thread_context, sizeof(struct get_thread_context_request) },
{ (void(*)())req_set_thread_context, sizeof(struct set_thread_context_request) },
{ (void(*)())req_get_selector_entry, sizeof(struct get_selector_entry_request) },
};
#endif /* WANT_REQUEST_HANDLERS */
......
......@@ -520,6 +520,37 @@ static int thread_queue_apc( struct thread *thread, void *func, void *param )
return 1;
}
/* retrieve an LDT selector entry */
static void get_selector_entry( struct thread *thread, int entry,
unsigned int *base, unsigned int *limit,
unsigned char *flags )
{
if (!thread->process->ldt_copy || !thread->process->ldt_flags)
{
set_error( STATUS_ACCESS_DENIED );
return;
}
if (entry >= 8192)
{
set_error( STATUS_INVALID_PARAMETER ); /* FIXME */
return;
}
suspend_thread( thread, 0 );
if (thread->attached)
{
unsigned char flags_buf[4];
int *addr = (int *)thread->process->ldt_copy + 2 * entry;
if (read_thread_int( thread, addr, base ) == -1) goto done;
if (read_thread_int( thread, addr + 1, limit ) == -1) goto done;
addr = (int *)thread->process->ldt_flags + (entry >> 2);
if (read_thread_int( thread, addr, (int *)flags_buf ) == -1) goto done;
*flags = flags_buf[entry & 3];
}
else set_error( STATUS_ACCESS_DENIED );
done:
resume_thread( thread );
}
/* kill a thread on the spot */
void kill_thread( struct thread *thread, int exit_code )
{
......@@ -689,3 +720,14 @@ DECL_HANDLER(get_apcs)
current->apc_count = 0;
}
}
/* fetch a selector entry for a thread */
DECL_HANDLER(get_selector_entry)
{
struct thread *thread;
if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
{
get_selector_entry( thread, req->entry, &req->base, &req->limit, &req->flags );
release_object( thread );
}
}
......@@ -239,6 +239,8 @@ static void dump_boot_done_request( const struct boot_done_request *req )
static void dump_init_process_request( const struct init_process_request *req )
{
fprintf( stderr, " ldt_copy=%p,", req->ldt_copy );
fprintf( stderr, " ldt_flags=%p", req->ldt_flags );
}
static void dump_init_process_reply( const struct init_process_request *req )
......@@ -1167,6 +1169,19 @@ static void dump_set_thread_context_request( const struct set_thread_context_req
dump_context( &req->context );
}
static void dump_get_selector_entry_request( const struct get_selector_entry_request *req )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " entry=%d", req->entry );
}
static void dump_get_selector_entry_reply( const struct get_selector_entry_request *req )
{
fprintf( stderr, " base=%08x,", req->base );
fprintf( stderr, " limit=%08x,", req->limit );
fprintf( stderr, " flags=%02x", req->flags );
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_new_thread_request,
......@@ -1260,6 +1275,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_cancel_timer_request,
(dump_func)dump_get_thread_context_request,
(dump_func)dump_set_thread_context_request,
(dump_func)dump_get_selector_entry_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
......@@ -1355,6 +1371,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)0,
(dump_func)dump_get_thread_context_reply,
(dump_func)0,
(dump_func)dump_get_selector_entry_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
......@@ -1450,6 +1467,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"cancel_timer",
"get_thread_context",
"set_thread_context",
"get_selector_entry",
};
/* ### make_requests end ### */
......
......@@ -11,6 +11,7 @@
"int" => "%d",
"long" => "%ld",
"char" => "%c",
"unsigned char" => "%02x",
"unsigned int" => "%08x",
"void*" => "%p",
"time_t" => "%ld",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment