Commit e6267369 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- changed ATOM support in wineserver to match NTDLL needs

- adapted accordingly kernel32 atom support
parent d7272ded
......@@ -1990,7 +1990,7 @@ struct get_selector_entry_reply
struct add_atom_request
{
struct request_header __header;
int local;
obj_handle_t table;
/* VARARG(name,unicode_str); */
};
struct add_atom_reply
......@@ -2004,8 +2004,8 @@ struct add_atom_reply
struct delete_atom_request
{
struct request_header __header;
obj_handle_t table;
atom_t atom;
int local;
};
struct delete_atom_reply
{
......@@ -2017,7 +2017,7 @@ struct delete_atom_reply
struct find_atom_request
{
struct request_header __header;
int local;
obj_handle_t table;
/* VARARG(name,unicode_str); */
};
struct find_atom_reply
......@@ -2028,21 +2028,49 @@ struct find_atom_reply
struct get_atom_name_request
struct get_atom_information_request
{
struct request_header __header;
obj_handle_t table;
atom_t atom;
int local;
};
struct get_atom_name_reply
struct get_atom_information_reply
{
struct reply_header __header;
int count;
int pinned;
/* VARARG(name,unicode_str); */
};
struct set_atom_information_request
{
struct request_header __header;
obj_handle_t table;
atom_t atom;
int pinned;
};
struct set_atom_information_reply
{
struct reply_header __header;
};
struct empty_atom_table_request
{
struct request_header __header;
obj_handle_t table;
int if_pinned;
};
struct empty_atom_table_reply
{
struct reply_header __header;
};
struct init_atom_table_request
{
struct request_header __header;
......@@ -2051,6 +2079,7 @@ struct init_atom_table_request
struct init_atom_table_reply
{
struct reply_header __header;
obj_handle_t table;
};
......@@ -3448,7 +3477,9 @@ enum request
REQ_add_atom,
REQ_delete_atom,
REQ_find_atom,
REQ_get_atom_name,
REQ_get_atom_information,
REQ_set_atom_information,
REQ_empty_atom_table,
REQ_init_atom_table,
REQ_get_msg_queue,
REQ_set_queue_mask,
......@@ -3645,7 +3676,9 @@ union generic_request
struct add_atom_request add_atom_request;
struct delete_atom_request delete_atom_request;
struct find_atom_request find_atom_request;
struct get_atom_name_request get_atom_name_request;
struct get_atom_information_request get_atom_information_request;
struct set_atom_information_request set_atom_information_request;
struct empty_atom_table_request empty_atom_table_request;
struct init_atom_table_request init_atom_table_request;
struct get_msg_queue_request get_msg_queue_request;
struct set_queue_mask_request set_queue_mask_request;
......@@ -3840,7 +3873,9 @@ union generic_reply
struct add_atom_reply add_atom_reply;
struct delete_atom_reply delete_atom_reply;
struct find_atom_reply find_atom_reply;
struct get_atom_name_reply get_atom_name_reply;
struct get_atom_information_reply get_atom_information_reply;
struct set_atom_information_reply set_atom_information_reply;
struct empty_atom_table_reply empty_atom_table_reply;
struct init_atom_table_reply init_atom_table_reply;
struct get_msg_queue_reply get_msg_queue_reply;
struct set_queue_mask_reply set_queue_mask_reply;
......@@ -3919,6 +3954,6 @@ union generic_reply
struct set_mailslot_info_reply set_mailslot_info_reply;
};
#define SERVER_PROTOCOL_VERSION 172
#define SERVER_PROTOCOL_VERSION 173
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -31,6 +31,7 @@
#include "request.h"
#include "object.h"
#include "process.h"
#include "handle.h"
#define HASH_SIZE 37
#define MIN_HASH_SIZE 4
......@@ -45,6 +46,7 @@ struct atom_entry
struct atom_entry *next; /* hash table list */
struct atom_entry *prev; /* hash table list */
int count; /* reference count */
int pinned; /* whether the atom is pinned or not */
int hash; /* string hash */
atom_t atom; /* atom handle */
WCHAR str[1]; /* atom string */
......@@ -185,8 +187,9 @@ static void atom_table_dump( struct object *obj, int verbose )
{
struct atom_entry *entry = table->handles[i];
if (!entry) continue;
fprintf( stderr, " %04x: ref=%d hash=%d \"", entry->atom, entry->count, entry->hash );
dump_strW( entry->str, strlenW(entry->str), stderr, "\"\"");
fprintf( stderr, " %04x: ref=%d pinned=%c hash=%d \"",
entry->atom, entry->count, entry->pinned ? 'Y' : 'N', entry->hash );
dump_strW( entry->str, strlenW( entry->str ), stderr, "\"\"");
fprintf( stderr, "\"\n" );
}
}
......@@ -249,6 +252,7 @@ static atom_t add_atom( struct atom_table *table, const WCHAR *str )
if ((entry->next = table->entries[hash])) entry->next->prev = entry;
table->entries[hash] = entry;
entry->count = 1;
entry->pinned = 0;
entry->hash = hash;
strcpyW( entry->str, str );
}
......@@ -302,53 +306,128 @@ void release_global_atom( atom_t atom )
if (atom >= MIN_STR_ATOM) delete_atom( global_table, atom );
}
static struct atom_table* get_table( obj_handle_t h )
{
struct atom_table *table;
if (h)
{
table = (struct atom_table*)get_handle_obj( current->process, h,
0, &atom_table_ops );
}
else
{
if (!global_table && !(global_table = create_table( HASH_SIZE )))
return NULL;
table = (struct atom_table*)grab_object( global_table );
}
return table;
}
/* add a global atom */
DECL_HANDLER(add_atom)
{
struct atom_table **table_ptr = req->local ? &current->process->atom_table : &global_table;
if (!*table_ptr) *table_ptr = create_table(0);
if (*table_ptr)
struct atom_table *table = get_table( req->table );
if (table)
{
const WCHAR *name = copy_request_name();
if (name) reply->atom = add_atom( *table_ptr, name );
if (name) reply->atom = add_atom( table, name );
release_object( table );
}
}
/* delete a global atom */
DECL_HANDLER(delete_atom)
{
delete_atom( req->local ? current->process->atom_table : global_table, req->atom );
struct atom_table *table = get_table( req->table );
if (table)
{
delete_atom( table, req->atom );
release_object( table );
}
}
/* find a global atom */
DECL_HANDLER(find_atom)
{
const WCHAR *name = copy_request_name();
if (name)
reply->atom = find_atom( req->local ? current->process->atom_table : global_table, name );
struct atom_table *table = get_table( req->table );
if (table)
{
const WCHAR *name = copy_request_name();
if (name)
reply->atom = find_atom( table, name );
release_object( table );
}
}
/* get global atom name */
DECL_HANDLER(get_atom_name)
DECL_HANDLER(get_atom_information)
{
struct atom_entry *entry;
size_t len = 0;
struct atom_table *table = get_table( req->table );
if (table)
{
struct atom_entry *entry;
reply->count = -1;
if ((entry = get_atom_entry( req->local ? current->process->atom_table : global_table,
req->atom )))
if ((entry = get_atom_entry( table, req->atom )))
{
size_t len = strlenW( entry->str ) * sizeof(WCHAR);
if (len <= get_reply_max_size()) set_reply_data( entry->str, len );
else set_error( STATUS_BUFFER_OVERFLOW );
reply->count = entry->count;
reply->pinned = entry->pinned;
}
else reply->count = -1;
release_object( table );
}
}
/* set global atom name */
DECL_HANDLER(set_atom_information)
{
struct atom_table *table = get_table( req->table );
if (table)
{
reply->count = entry->count;
len = strlenW( entry->str ) * sizeof(WCHAR);
if (len <= get_reply_max_size()) set_reply_data( entry->str, len );
else set_error( STATUS_BUFFER_OVERFLOW );
struct atom_entry *entry;
if ((entry = get_atom_entry( table, req->atom )))
{
if (req->pinned) entry->pinned = 1;
}
release_object( table );
}
}
/* init the process atom table */
/* init a (local) atom table */
DECL_HANDLER(init_atom_table)
{
if (!current->process->atom_table)
current->process->atom_table = create_table( req->entries );
struct atom_table* table;
table = create_table( req->entries );
reply->table = alloc_handle( current->process, table, 0, FALSE);
release_object( table );
}
/* set global atom name */
DECL_HANDLER(empty_atom_table)
{
struct atom_table *table = get_table( req->table );
if (table)
{
int i;
struct atom_entry *entry;
for (i = 0; i <= table->last; i++)
{
entry = table->handles[i];
if (entry && (!entry->pinned || req->if_pinned))
{
if (entry->next) entry->next->prev = entry->prev;
if (entry->prev) entry->prev->next = entry->next;
else table->entries[entry->hash] = entry->next;
table->handles[i] = NULL;
free( entry );
}
}
release_object( table );
}
}
......@@ -278,7 +278,6 @@ struct thread *create_process( int fd )
process->startup_info = NULL;
process->idle_event = NULL;
process->queue = NULL;
process->atom_table = NULL;
process->peb = NULL;
process->ldt_copy = NULL;
process->exe.file = NULL;
......@@ -422,7 +421,6 @@ static void process_destroy( struct object *obj )
list_remove( &process->entry );
if (process->idle_event) release_object( process->idle_event );
if (process->queue) release_object( process->queue );
if (process->atom_table) release_object( process->atom_table );
if (process->exe.file) release_object( process->exe.file );
if (process->exe.filename) free( process->exe.filename );
if (process->id) free_ptid( process->id );
......
......@@ -72,7 +72,6 @@ struct process
struct startup_info *startup_info; /* startup info while init is in progress */
struct event *idle_event; /* event for input idle */
struct msg_queue *queue; /* main message queue */
struct atom_table *atom_table; /* pointer to local atom table */
struct token *token; /* security token associated with this process */
struct process_dll exe; /* main exe file */
struct list dlls; /* list of loaded dlls */
......
......@@ -1418,7 +1418,7 @@ enum char_info_mode
/* Add an atom */
@REQ(add_atom)
int local; /* is atom in local process table? */
obj_handle_t table; /* which table to add atom to */
VARARG(name,unicode_str); /* atom name */
@REPLY
atom_t atom; /* resulting atom */
......@@ -1427,33 +1427,51 @@ enum char_info_mode
/* Delete an atom */
@REQ(delete_atom)
obj_handle_t table; /* which table to delete atom from */
atom_t atom; /* atom handle */
int local; /* is atom in local process table? */
@END
/* Find an atom */
@REQ(find_atom)
int local; /* is atom in local process table? */
obj_handle_t table; /* which table to find atom from */
VARARG(name,unicode_str); /* atom name */
@REPLY
atom_t atom; /* atom handle */
@END
/* Get an atom name */
@REQ(get_atom_name)
/* Get information about an atom */
@REQ(get_atom_information)
obj_handle_t table; /* which table to find atom from */
atom_t atom; /* atom handle */
int local; /* is atom in local process table? */
@REPLY
int count; /* atom lock count */
int pinned; /* whether the atom has been pinned */
VARARG(name,unicode_str); /* atom name */
@END
/* Init the process atom table */
/* Set information about an atom */
@REQ(set_atom_information)
obj_handle_t table; /* which table to find atom from */
atom_t atom; /* atom handle */
int pinned; /* whether to bump atom information */
@END
/* Empty an atom table */
@REQ(empty_atom_table)
obj_handle_t table; /* which table to find atom from */
int if_pinned; /* whether to delete pinned atoms */
@END
/* Init an atom table */
@REQ(init_atom_table)
int entries; /* number of entries */
int entries; /* number of entries (only for local) */
@REPLY
obj_handle_t table; /* handle to the atom table */
@END
......
......@@ -216,7 +216,9 @@ DECL_HANDLER(get_selector_entry);
DECL_HANDLER(add_atom);
DECL_HANDLER(delete_atom);
DECL_HANDLER(find_atom);
DECL_HANDLER(get_atom_name);
DECL_HANDLER(get_atom_information);
DECL_HANDLER(set_atom_information);
DECL_HANDLER(empty_atom_table);
DECL_HANDLER(init_atom_table);
DECL_HANDLER(get_msg_queue);
DECL_HANDLER(set_queue_mask);
......@@ -412,7 +414,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_add_atom,
(req_handler)req_delete_atom,
(req_handler)req_find_atom,
(req_handler)req_get_atom_name,
(req_handler)req_get_atom_information,
(req_handler)req_set_atom_information,
(req_handler)req_empty_atom_table,
(req_handler)req_init_atom_table,
(req_handler)req_get_msg_queue,
(req_handler)req_set_queue_mask,
......
......@@ -1758,7 +1758,7 @@ static void dump_get_selector_entry_reply( const struct get_selector_entry_reply
static void dump_add_atom_request( const struct add_atom_request *req )
{
fprintf( stderr, " local=%d,", req->local );
fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size );
}
......@@ -1770,13 +1770,13 @@ static void dump_add_atom_reply( const struct add_atom_reply *req )
static void dump_delete_atom_request( const struct delete_atom_request *req )
{
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " local=%d", req->local );
fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " atom=%04x", req->atom );
}
static void dump_find_atom_request( const struct find_atom_request *req )
{
fprintf( stderr, " local=%d,", req->local );
fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size );
}
......@@ -1786,24 +1786,43 @@ static void dump_find_atom_reply( const struct find_atom_reply *req )
fprintf( stderr, " atom=%04x", req->atom );
}
static void dump_get_atom_name_request( const struct get_atom_name_request *req )
static void dump_get_atom_information_request( const struct get_atom_information_request *req )
{
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " local=%d", req->local );
fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " atom=%04x", req->atom );
}
static void dump_get_atom_name_reply( const struct get_atom_name_reply *req )
static void dump_get_atom_information_reply( const struct get_atom_information_reply *req )
{
fprintf( stderr, " count=%d,", req->count );
fprintf( stderr, " pinned=%d,", req->pinned );
fprintf( stderr, " name=" );
dump_varargs_unicode_str( cur_size );
}
static void dump_set_atom_information_request( const struct set_atom_information_request *req )
{
fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " atom=%04x,", req->atom );
fprintf( stderr, " pinned=%d", req->pinned );
}
static void dump_empty_atom_table_request( const struct empty_atom_table_request *req )
{
fprintf( stderr, " table=%p,", req->table );
fprintf( stderr, " if_pinned=%d", req->if_pinned );
}
static void dump_init_atom_table_request( const struct init_atom_table_request *req )
{
fprintf( stderr, " entries=%d", req->entries );
}
static void dump_init_atom_table_reply( const struct init_atom_table_reply *req )
{
fprintf( stderr, " table=%p", req->table );
}
static void dump_get_msg_queue_request( const struct get_msg_queue_request *req )
{
}
......@@ -2885,7 +2904,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_add_atom_request,
(dump_func)dump_delete_atom_request,
(dump_func)dump_find_atom_request,
(dump_func)dump_get_atom_name_request,
(dump_func)dump_get_atom_information_request,
(dump_func)dump_set_atom_information_request,
(dump_func)dump_empty_atom_table_request,
(dump_func)dump_init_atom_table_request,
(dump_func)dump_get_msg_queue_request,
(dump_func)dump_set_queue_mask_request,
......@@ -3078,8 +3099,10 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_add_atom_reply,
(dump_func)0,
(dump_func)dump_find_atom_reply,
(dump_func)dump_get_atom_name_reply,
(dump_func)dump_get_atom_information_reply,
(dump_func)0,
(dump_func)0,
(dump_func)dump_init_atom_table_reply,
(dump_func)dump_get_msg_queue_reply,
(dump_func)dump_set_queue_mask_reply,
(dump_func)dump_get_queue_status_reply,
......@@ -3271,7 +3294,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"add_atom",
"delete_atom",
"find_atom",
"get_atom_name",
"get_atom_information",
"set_atom_information",
"empty_atom_table",
"init_atom_table",
"get_msg_queue",
"set_queue_mask",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment