Redesign of the server communication protocol to allow arbitrary sized
data to be exchanged.
Split request and reply structures to make backwards compatibility
easier.
Moved many console functions to dlls/kernel, added code page support,
changed a few requests to behave properly with the new protocol.
diff --git a/server/queue.c b/server/queue.c
index b72f31c..87e85a0 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -330,10 +330,29 @@
}
/* receive a message, removing it from the sent queue */
-static void receive_message( struct msg_queue *queue, struct message *msg )
+static void receive_message( struct msg_queue *queue, struct message *msg,
+ struct get_message_reply *reply )
{
struct message_result *result = msg->result;
+ reply->total = msg->data_size;
+ if (msg->data_size > get_reply_max_size())
+ {
+ set_error( STATUS_BUFFER_OVERFLOW );
+ return;
+ }
+ reply->type = msg->type;
+ reply->win = msg->win;
+ reply->msg = msg->msg;
+ reply->wparam = msg->wparam;
+ reply->lparam = msg->lparam;
+ reply->x = msg->x;
+ reply->y = msg->y;
+ reply->time = msg->time;
+ reply->info = msg->info;
+
+ if (msg->data) set_reply_data_ptr( msg->data, msg->data_size );
+
unlink_message( &queue->msg_list[SEND_MESSAGE], msg );
/* put the result on the receiver result stack */
if (result)
@@ -341,14 +360,13 @@
result->recv_next = queue->recv_result;
queue->recv_result = result;
}
- if (msg->data) free( msg->data );
free( msg );
if (!queue->msg_list[SEND_MESSAGE].first) clear_queue_bits( queue, QS_SENDMESSAGE );
}
/* set the result of the current received message */
static void reply_message( struct msg_queue *queue, unsigned int result,
- unsigned int error, int remove, void *data, size_t len )
+ unsigned int error, int remove, const void *data, size_t len )
{
struct message_result *res = queue->recv_result;
@@ -656,8 +674,8 @@
{
struct msg_queue *queue = get_current_queue();
- req->handle = 0;
- if (queue) req->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
+ reply->handle = 0;
+ if (queue) reply->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
}
@@ -670,8 +688,8 @@
{
queue->wake_mask = req->wake_mask;
queue->changed_mask = req->changed_mask;
- req->wake_bits = queue->wake_bits;
- req->changed_bits = queue->changed_bits;
+ reply->wake_bits = queue->wake_bits;
+ reply->changed_bits = queue->changed_bits;
if (is_signaled( queue ))
{
/* if skip wait is set, do what would have been done in the subsequent wait */
@@ -688,11 +706,11 @@
struct msg_queue *queue = current->queue;
if (queue)
{
- req->wake_bits = queue->wake_bits;
- req->changed_bits = queue->changed_bits;
+ reply->wake_bits = queue->wake_bits;
+ reply->changed_bits = queue->changed_bits;
if (req->clear) queue->changed_bits = 0;
}
- else req->wake_bits = req->changed_bits = 0;
+ else reply->wake_bits = reply->changed_bits = 0;
}
@@ -731,8 +749,8 @@
switch(msg->type)
{
case MSG_OTHER_PROCESS:
- msg->data_size = get_req_data_size(req);
- if (msg->data_size && !(msg->data = memdup( get_req_data(req), msg->data_size )))
+ msg->data_size = get_req_data_size();
+ if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size )))
{
free( msg );
break;
@@ -779,31 +797,26 @@
release_object( thread );
}
-/* store a message contents into the request buffer; helper for get_message */
-inline static void put_req_message( struct get_message_request *req, const struct message *msg )
-{
- int len = min( get_req_data_size(req), msg->data_size );
-
- req->type = msg->type;
- req->win = msg->win;
- req->msg = msg->msg;
- req->wparam = msg->wparam;
- req->lparam = msg->lparam;
- req->x = msg->x;
- req->y = msg->y;
- req->time = msg->time;
- req->info = msg->info;
- if (len) memcpy( get_req_data(req), msg->data, len );
- set_req_data_size( req, len );
-}
-
/* return a message to the application, removing it from the queue if needed */
-static void return_message_to_app( struct msg_queue *queue, struct get_message_request *req,
+static void return_message_to_app( struct msg_queue *queue, int flags,
+ struct get_message_reply *reply,
struct message *msg, enum message_kind kind )
{
- put_req_message( req, msg );
+ assert( !msg->data_size ); /* posted messages can't have data */
+
+ reply->type = msg->type;
+ reply->win = msg->win;
+ reply->msg = msg->msg;
+ reply->wparam = msg->wparam;
+ reply->lparam = msg->lparam;
+ reply->x = msg->x;
+ reply->y = msg->y;
+ reply->time = msg->time;
+ reply->info = msg->info;
+ reply->total = 0;
+
/* raw messages always get removed */
- if ((msg->type == MSG_HARDWARE_RAW) || (req->flags & GET_MSG_REMOVE))
+ if ((msg->type == MSG_HARDWARE_RAW) || (flags & GET_MSG_REMOVE))
{
queue->last_msg = NULL;
remove_queue_message( queue, msg, kind );
@@ -843,20 +856,14 @@
struct msg_queue *queue = get_current_queue();
user_handle_t get_win = get_user_full_handle( req->get_win );
- if (!queue)
- {
- set_req_data_size( req, 0 );
- return;
- }
+ if (!queue) return;
/* first check for sent messages */
if ((msg = queue->msg_list[SEND_MESSAGE].first))
{
- put_req_message( req, msg );
- receive_message( queue, msg );
+ receive_message( queue, msg, reply );
return;
}
- set_req_data_size( req, 0 ); /* only sent messages can have data */
if (req->flags & GET_MSG_SENT_ONLY) goto done; /* nothing else to check */
/* if requested, remove the last returned but not yet removed message */
@@ -871,7 +878,7 @@
if ((msg = find_matching_message( &queue->msg_list[POST_MESSAGE], get_win,
req->get_first, req->get_last )))
{
- return_message_to_app( queue, req, msg, POST_MESSAGE );
+ return_message_to_app( queue, req->flags, reply, msg, POST_MESSAGE );
return;
}
@@ -879,30 +886,30 @@
if ((msg = find_matching_message( &queue->msg_list[COOKED_HW_MESSAGE], get_win,
req->get_first, req->get_last )))
{
- return_message_to_app( queue, req, msg, COOKED_HW_MESSAGE );
+ return_message_to_app( queue, req->flags, reply, msg, COOKED_HW_MESSAGE );
return;
}
/* then check for any raw hardware message */
if ((msg = queue->msg_list[RAW_HW_MESSAGE].first))
{
- return_message_to_app( queue, req, msg, RAW_HW_MESSAGE );
+ return_message_to_app( queue, req->flags, reply, msg, RAW_HW_MESSAGE );
return;
}
/* now check for WM_PAINT */
if (queue->paint_count &&
(WM_PAINT >= req->get_first) && (WM_PAINT <= req->get_last) &&
- (req->win = find_window_to_repaint( get_win, current )))
+ (reply->win = find_window_to_repaint( get_win, current )))
{
- req->type = MSG_POSTED;
- req->msg = WM_PAINT;
- req->wparam = 0;
- req->lparam = 0;
- req->x = 0;
- req->y = 0;
- req->time = get_tick_count();
- req->info = 0;
+ reply->type = MSG_POSTED;
+ reply->msg = WM_PAINT;
+ reply->wparam = 0;
+ reply->lparam = 0;
+ reply->x = 0;
+ reply->y = 0;
+ reply->time = get_tick_count();
+ reply->info = 0;
return;
}
@@ -910,15 +917,15 @@
if ((timer = find_expired_timer( queue, get_win, req->get_first,
req->get_last, (req->flags & GET_MSG_REMOVE) )))
{
- req->type = MSG_POSTED;
- req->win = timer->win;
- req->msg = timer->msg;
- req->wparam = timer->id;
- req->lparam = timer->lparam;
- req->x = 0;
- req->y = 0;
- req->time = get_tick_count();
- req->info = 0;
+ reply->type = MSG_POSTED;
+ reply->win = timer->win;
+ reply->msg = timer->msg;
+ reply->wparam = timer->id;
+ reply->lparam = timer->lparam;
+ reply->x = 0;
+ reply->y = 0;
+ reply->time = get_tick_count();
+ reply->info = 0;
return;
}
@@ -932,7 +939,7 @@
{
if (current->queue && current->queue->recv_result)
reply_message( current->queue, req->result, 0, req->remove,
- get_req_data(req), get_req_data_size(req) );
+ get_req_data(), get_req_data_size() );
else
set_error( STATUS_ACCESS_DENIED );
}
@@ -942,26 +949,24 @@
DECL_HANDLER(get_message_reply)
{
struct msg_queue *queue = current->queue;
- size_t data_len = 0;
if (queue)
{
struct message_result *result = queue->send_result;
set_error( STATUS_PENDING );
- req->result = 0;
+ reply->result = 0;
if (result && (result->replied || req->cancel))
{
if (result->replied)
{
- req->result = result->result;
+ reply->result = result->result;
set_error( result->error );
if (result->data)
{
- data_len = min( result->data_size, get_req_data_size(req) );
- memcpy( get_req_data(req), result->data, data_len );
- free( result->data );
+ size_t data_len = min( result->data_size, get_reply_max_size() );
+ set_reply_data_ptr( result->data, data_len );
result->data = NULL;
result->data_size = 0;
}
@@ -974,7 +979,6 @@
}
}
else set_error( STATUS_ACCESS_DENIED );
- set_req_data_size( req, data_len );
}