Cosmetics.
[wine.git] / server / request.c
blob977b4bd8cdc854523cf8495c9f51487dba2da442
1 /*
2 * Server-side request handling
4 * Copyright (C) 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <stdarg.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <signal.h>
13 #include <sys/types.h>
14 #include <sys/uio.h>
15 #include <unistd.h>
17 #include "winerror.h"
18 #include "winnt.h"
19 #include "winbase.h"
20 #include "wincon.h"
21 #define WANT_REQUEST_HANDLERS
22 #include "server.h"
23 #include "server/request.h"
24 #include "server/process.h"
25 #include "server/thread.h"
27 /* check that the string is NULL-terminated and that the len is correct */
28 #define CHECK_STRING(func,str,len) \
29 do { if (((str)[(len)-1] || strlen(str) != (len)-1)) \
30 fatal_protocol_error( "%s: invalid string '%.*s'\n", (func), (len), (str) ); \
31 } while(0)
33 struct thread *current = NULL; /* thread handling the current request */
35 /* complain about a protocol error and terminate the client connection */
36 static void fatal_protocol_error( const char *err, ... )
38 va_list args;
40 va_start( args, err );
41 fprintf( stderr, "Protocol error:%p: ", current );
42 vfprintf( stderr, err, args );
43 va_end( args );
44 remove_client( current->client_fd, -2 );
47 /* call a request handler */
48 void call_req_handler( struct thread *thread, enum request req,
49 void *data, int len, int fd )
51 const struct handler *handler = &req_handlers[req];
52 char *ptr;
54 current = thread;
55 if ((req < 0) || (req >= REQ_NB_REQUESTS))
57 fatal_protocol_error( "unknown request %d\n", req );
58 return;
61 if (len < handler->min_size)
63 fatal_protocol_error( "req %d bad length %d < %d)\n", req, len, handler->min_size );
64 return;
67 /* now call the handler */
68 if (current)
70 CLEAR_ERROR();
71 if (debug_level) trace_request( req, data, len, fd );
73 len -= handler->min_size;
74 ptr = (char *)data + handler->min_size;
75 handler->handler( data, ptr, len, fd );
76 current = NULL;
79 /* handle a client timeout (unused for now) */
80 void call_timeout_handler( struct thread *thread )
82 current = thread;
83 if (debug_level) trace_timeout();
84 CLEAR_ERROR();
85 thread_timeout();
86 current = NULL;
89 /* a thread has been killed */
90 void call_kill_handler( struct thread *thread, int exit_code )
92 /* must be reentrant WRT call_req_handler */
93 struct thread *old_current = current;
94 current = thread;
95 if (current)
97 if (debug_level) trace_kill( exit_code );
98 thread_killed( current, exit_code );
100 current = (old_current != thread) ? old_current : NULL;
104 /* create a new process */
105 DECL_HANDLER(new_process)
107 struct new_process_reply reply;
108 struct process *process;
110 if ((process = create_process( req )))
112 reply.pid = process;
113 reply.handle = alloc_handle( current->process, process,
114 PROCESS_ALL_ACCESS, req->inherit );
115 release_object( process );
117 else
119 reply.handle = -1;
120 reply.pid = NULL;
122 send_reply( current, -1, 1, &reply, sizeof(reply) );
125 /* create a new thread */
126 DECL_HANDLER(new_thread)
128 struct new_thread_reply reply;
129 int new_fd;
131 if ((new_fd = dup(fd)) != -1)
133 reply.tid = create_thread( new_fd, req->pid, req->suspend,
134 req->inherit, &reply.handle );
135 if (!reply.tid) close( new_fd );
137 else
138 SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );
140 send_reply( current, -1, 1, &reply, sizeof(reply) );
143 /* initialize a new process */
144 DECL_HANDLER(init_process)
146 struct init_process_reply reply;
147 if (current->state != RUNNING)
149 fatal_protocol_error( "init_process: init_thread not called yet\n" );
150 return;
152 if (!get_process_init_info( current->process, &reply ))
154 fatal_protocol_error( "init_process: called twice\n" );
155 return;
157 send_reply( current, -1, 1, &reply, sizeof(reply) );
160 /* initialize a new thread */
161 DECL_HANDLER(init_thread)
163 if (current->state != STARTING)
165 fatal_protocol_error( "init_thread: already running\n" );
166 return;
168 current->state = RUNNING;
169 current->unix_pid = req->unix_pid;
170 if (current->suspend > 0)
171 kill( current->unix_pid, SIGSTOP );
172 send_reply( current, -1, 0 );
175 /* set the debug level */
176 DECL_HANDLER(set_debug)
178 debug_level = req->level;
179 /* Make sure last_req is initialized */
180 current->last_req = REQ_SET_DEBUG;
181 CLEAR_ERROR();
182 send_reply( current, -1, 0 );
185 /* terminate a process */
186 DECL_HANDLER(terminate_process)
188 struct process *process;
190 if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
192 kill_process( process, req->exit_code );
193 release_object( process );
195 if (current) send_reply( current, -1, 0 );
198 /* terminate a thread */
199 DECL_HANDLER(terminate_thread)
201 struct thread *thread;
203 if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE )))
205 kill_thread( thread, req->exit_code );
206 release_object( thread );
208 if (current) send_reply( current, -1, 0 );
211 /* close a handle */
212 DECL_HANDLER(close_handle)
214 close_handle( current->process, req->handle );
215 send_reply( current, -1, 0 );
218 /* get information about a handle */
219 DECL_HANDLER(get_handle_info)
221 struct get_handle_info_reply reply;
222 reply.flags = set_handle_info( current->process, req->handle, 0, 0 );
223 send_reply( current, -1, 1, &reply, sizeof(reply) );
226 /* set a handle information */
227 DECL_HANDLER(set_handle_info)
229 set_handle_info( current->process, req->handle, req->mask, req->flags );
230 send_reply( current, -1, 0 );
233 /* duplicate a handle */
234 DECL_HANDLER(dup_handle)
236 struct dup_handle_reply reply = { -1 };
237 struct process *src, *dst;
239 if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
241 if (req->options & DUP_HANDLE_MAKE_GLOBAL)
243 reply.handle = duplicate_handle( src, req->src_handle, NULL,
244 req->access, req->inherit, req->options );
246 else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
248 reply.handle = duplicate_handle( src, req->src_handle, dst,
249 req->access, req->inherit, req->options );
250 release_object( dst );
252 /* close the handle no matter what happened */
253 if (req->options & DUP_HANDLE_CLOSE_SOURCE)
254 close_handle( src, req->src_handle );
255 release_object( src );
257 send_reply( current, -1, 1, &reply, sizeof(reply) );
260 /* fetch information about a process */
261 DECL_HANDLER(get_process_info)
263 struct process *process;
264 struct get_process_info_reply reply = { 0, 0, 0 };
266 if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
268 get_process_info( process, &reply );
269 release_object( process );
271 send_reply( current, -1, 1, &reply, sizeof(reply) );
274 /* set information about a process */
275 DECL_HANDLER(set_process_info)
277 struct process *process;
279 if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
281 set_process_info( process, req );
282 release_object( process );
284 send_reply( current, -1, 0 );
287 /* fetch information about a thread */
288 DECL_HANDLER(get_thread_info)
290 struct thread *thread;
291 struct get_thread_info_reply reply = { 0, 0 };
293 if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
295 get_thread_info( thread, &reply );
296 release_object( thread );
298 send_reply( current, -1, 1, &reply, sizeof(reply) );
301 /* set information about a thread */
302 DECL_HANDLER(set_thread_info)
304 struct thread *thread;
306 if ((thread = get_thread_from_handle( req->handle, THREAD_SET_INFORMATION )))
308 set_thread_info( thread, req );
309 release_object( thread );
311 send_reply( current, -1, 0 );
314 /* suspend a thread */
315 DECL_HANDLER(suspend_thread)
317 struct thread *thread;
318 struct suspend_thread_reply reply = { -1 };
319 if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
321 reply.count = suspend_thread( thread );
322 release_object( thread );
324 send_reply( current, -1, 1, &reply, sizeof(reply) );
328 /* resume a thread */
329 DECL_HANDLER(resume_thread)
331 struct thread *thread;
332 struct resume_thread_reply reply = { -1 };
333 if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
335 reply.count = resume_thread( thread );
336 release_object( thread );
338 send_reply( current, -1, 1, &reply, sizeof(reply) );
342 /* queue an APC for a thread */
343 DECL_HANDLER(queue_apc)
345 struct thread *thread;
346 if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
348 thread_queue_apc( thread, req->func, req->param );
349 release_object( thread );
351 send_reply( current, -1, 0 );
354 /* open a handle to a process */
355 DECL_HANDLER(open_process)
357 struct open_process_reply reply = { -1 };
358 struct process *process = get_process_from_id( req->pid );
359 if (process)
361 reply.handle = alloc_handle( current->process, process,
362 req->access, req->inherit );
363 release_object( process );
365 send_reply( current, -1, 1, &reply, sizeof(reply) );
368 /* select on a handle list */
369 DECL_HANDLER(select)
371 if (len != req->count * sizeof(int))
372 fatal_protocol_error( "select: bad length %d for %d handles\n",
373 len, req->count );
374 sleep_on( current, req->count, (int *)data, req->flags, req->timeout );
377 /* create an event */
378 DECL_HANDLER(create_event)
380 struct create_event_reply reply = { -1 };
381 struct object *obj;
382 char *name = (char *)data;
383 if (!len) name = NULL;
384 else CHECK_STRING( "create_event", name, len );
386 obj = create_event( name, req->manual_reset, req->initial_state );
387 if (obj)
389 reply.handle = alloc_handle( current->process, obj, EVENT_ALL_ACCESS, req->inherit );
390 release_object( obj );
392 send_reply( current, -1, 1, &reply, sizeof(reply) );
395 /* do an event operation */
396 DECL_HANDLER(event_op)
398 switch(req->op)
400 case PULSE_EVENT:
401 pulse_event( req->handle );
402 break;
403 case SET_EVENT:
404 set_event( req->handle );
405 break;
406 case RESET_EVENT:
407 reset_event( req->handle );
408 break;
409 default:
410 fatal_protocol_error( "event_op: invalid operation %d\n", req->op );
412 send_reply( current, -1, 0 );
415 /* create a mutex */
416 DECL_HANDLER(create_mutex)
418 struct create_mutex_reply reply = { -1 };
419 struct object *obj;
420 char *name = (char *)data;
421 if (!len) name = NULL;
422 else CHECK_STRING( "create_mutex", name, len );
424 obj = create_mutex( name, req->owned );
425 if (obj)
427 reply.handle = alloc_handle( current->process, obj, MUTEX_ALL_ACCESS, req->inherit );
428 release_object( obj );
430 send_reply( current, -1, 1, &reply, sizeof(reply) );
433 /* release a mutex */
434 DECL_HANDLER(release_mutex)
436 if (release_mutex( req->handle )) CLEAR_ERROR();
437 send_reply( current, -1, 0 );
440 /* create a semaphore */
441 DECL_HANDLER(create_semaphore)
443 struct create_semaphore_reply reply = { -1 };
444 struct object *obj;
445 char *name = (char *)data;
446 if (!len) name = NULL;
447 else CHECK_STRING( "create_semaphore", name, len );
449 obj = create_semaphore( name, req->initial, req->max );
450 if (obj)
452 reply.handle = alloc_handle( current->process, obj, SEMAPHORE_ALL_ACCESS, req->inherit );
453 release_object( obj );
455 send_reply( current, -1, 1, &reply, sizeof(reply) );
458 /* release a semaphore */
459 DECL_HANDLER(release_semaphore)
461 struct release_semaphore_reply reply;
462 if (release_semaphore( req->handle, req->count, &reply.prev_count )) CLEAR_ERROR();
463 send_reply( current, -1, 1, &reply, sizeof(reply) );
466 /* open a handle to a named object (event, mutex, semaphore) */
467 DECL_HANDLER(open_named_obj)
469 struct open_named_obj_reply reply;
470 char *name = (char *)data;
471 if (!len) name = NULL;
472 else CHECK_STRING( "open_named_obj", name, len );
474 switch(req->type)
476 case OPEN_EVENT:
477 reply.handle = open_event( req->access, req->inherit, name );
478 break;
479 case OPEN_MUTEX:
480 reply.handle = open_mutex( req->access, req->inherit, name );
481 break;
482 case OPEN_SEMAPHORE:
483 reply.handle = open_semaphore( req->access, req->inherit, name );
484 break;
485 case OPEN_MAPPING:
486 reply.handle = open_mapping( req->access, req->inherit, name );
487 break;
488 default:
489 fatal_protocol_error( "open_named_obj: invalid type %d\n", req->type );
491 send_reply( current, -1, 1, &reply, sizeof(reply) );
494 /* create a file */
495 DECL_HANDLER(create_file)
497 struct create_file_reply reply = { -1 };
498 struct object *obj;
499 char *name = (char *)data;
500 if (!len) name = NULL;
501 else CHECK_STRING( "create_file", name, len );
503 if ((obj = create_file( fd, name, req->access,
504 req->sharing, req->create, req->attrs )) != NULL)
506 reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
507 release_object( obj );
509 send_reply( current, -1, 1, &reply, sizeof(reply) );
512 /* get a Unix fd to read from a file */
513 DECL_HANDLER(get_read_fd)
515 struct object *obj;
516 int read_fd;
518 if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
520 read_fd = obj->ops->get_read_fd( obj );
521 release_object( obj );
523 else read_fd = -1;
524 send_reply( current, read_fd, 0 );
527 /* get a Unix fd to write to a file */
528 DECL_HANDLER(get_write_fd)
530 struct object *obj;
531 int write_fd;
533 if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
535 write_fd = obj->ops->get_write_fd( obj );
536 release_object( obj );
538 else write_fd = -1;
539 send_reply( current, write_fd, 0 );
542 /* set a file current position */
543 DECL_HANDLER(set_file_pointer)
545 struct set_file_pointer_reply reply = { req->low, req->high };
546 set_file_pointer( req->handle, &reply.low, &reply.high, req->whence );
547 send_reply( current, -1, 1, &reply, sizeof(reply) );
550 /* truncate (or extend) a file */
551 DECL_HANDLER(truncate_file)
553 truncate_file( req->handle );
554 send_reply( current, -1, 0 );
557 /* flush a file buffers */
558 DECL_HANDLER(flush_file)
560 struct object *obj;
562 if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
564 obj->ops->flush( obj );
565 release_object( obj );
567 send_reply( current, -1, 0 );
570 /* set a file access and modification times */
571 DECL_HANDLER(set_file_time)
573 set_file_time( req->handle, req->access_time, req->write_time );
574 send_reply( current, -1, 0 );
577 /* get a file information */
578 DECL_HANDLER(get_file_info)
580 struct object *obj;
581 struct get_file_info_reply reply;
583 if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
585 obj->ops->get_file_info( obj, &reply );
586 release_object( obj );
588 send_reply( current, -1, 1, &reply, sizeof(reply) );
591 /* lock a region of a file */
592 DECL_HANDLER(lock_file)
594 struct file *file;
596 if ((file = get_file_obj( current->process, req->handle, 0 )))
598 file_lock( file, req->offset_high, req->offset_low,
599 req->count_high, req->count_low );
600 release_object( file );
602 send_reply( current, -1, 0 );
606 /* unlock a region of a file */
607 DECL_HANDLER(unlock_file)
609 struct file *file;
611 if ((file = get_file_obj( current->process, req->handle, 0 )))
613 file_unlock( file, req->offset_high, req->offset_low,
614 req->count_high, req->count_low );
615 release_object( file );
617 send_reply( current, -1, 0 );
621 /* create an anonymous pipe */
622 DECL_HANDLER(create_pipe)
624 struct create_pipe_reply reply = { -1, -1 };
625 struct object *obj[2];
626 if (create_pipe( obj ))
628 reply.handle_read = alloc_handle( current->process, obj[0],
629 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
630 req->inherit );
631 if (reply.handle_read != -1)
633 reply.handle_write = alloc_handle( current->process, obj[1],
634 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
635 req->inherit );
636 if (reply.handle_write == -1)
637 close_handle( current->process, reply.handle_read );
639 release_object( obj[0] );
640 release_object( obj[1] );
642 send_reply( current, -1, 1, &reply, sizeof(reply) );
645 /* allocate a console for the current process */
646 DECL_HANDLER(alloc_console)
648 alloc_console( current->process );
649 send_reply( current, -1, 0 );
652 /* free the console of the current process */
653 DECL_HANDLER(free_console)
655 free_console( current->process );
656 send_reply( current, -1, 0 );
659 /* open a handle to the process console */
660 DECL_HANDLER(open_console)
662 struct object *obj;
663 struct open_console_reply reply = { -1 };
664 if ((obj = get_console( current->process, req->output )))
666 reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
667 release_object( obj );
669 send_reply( current, -1, 1, &reply, sizeof(reply) );
672 /* set info about a console (output only) */
673 DECL_HANDLER(set_console_info)
675 char *name = (char *)data;
676 if (!len) name = NULL;
677 else CHECK_STRING( "set_console_info", name, len );
678 set_console_info( req->handle, req, name );
679 send_reply( current, -1, 0 );
682 /* get info about a console (output only) */
683 DECL_HANDLER(get_console_info)
685 struct get_console_info_reply reply;
686 const char *title;
687 get_console_info( req->handle, &reply, &title );
688 send_reply( current, -1, 2, &reply, sizeof(reply),
689 title, title ? strlen(title)+1 : 0 );
692 /* set a console fd */
693 DECL_HANDLER(set_console_fd)
695 set_console_fd( req->handle, fd, req->pid );
696 send_reply( current, -1, 0 );
699 /* get a console mode (input or output) */
700 DECL_HANDLER(get_console_mode)
702 struct get_console_mode_reply reply;
703 get_console_mode( req->handle, &reply.mode );
704 send_reply( current, -1, 1, &reply, sizeof(reply) );
707 /* set a console mode (input or output) */
708 DECL_HANDLER(set_console_mode)
710 set_console_mode( req->handle, req->mode );
711 send_reply( current, -1, 0 );
714 /* add input records to a console input queue */
715 DECL_HANDLER(write_console_input)
717 struct write_console_input_reply reply;
718 INPUT_RECORD *records = (INPUT_RECORD *)data;
720 if (len != req->count * sizeof(INPUT_RECORD))
721 fatal_protocol_error( "write_console_input: bad length %d for %d records\n",
722 len, req->count );
723 reply.written = write_console_input( req->handle, req->count, records );
724 send_reply( current, -1, 1, &reply, sizeof(reply) );
727 /* fetch input records from a console input queue */
728 DECL_HANDLER(read_console_input)
730 read_console_input( req->handle, req->count, req->flush );
733 /* create a change notification */
734 DECL_HANDLER(create_change_notification)
736 struct object *obj;
737 struct create_change_notification_reply reply = { -1 };
739 if ((obj = create_change_notification( req->subtree, req->filter )))
741 reply.handle = alloc_handle( current->process, obj,
742 STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
743 release_object( obj );
745 send_reply( current, -1, 1, &reply, sizeof(reply) );
748 /* create a file mapping */
749 DECL_HANDLER(create_mapping)
751 struct object *obj;
752 struct create_mapping_reply reply = { -1 };
753 char *name = (char *)data;
754 if (!len) name = NULL;
755 else CHECK_STRING( "create_mapping", name, len );
757 if ((obj = create_mapping( req->size_high, req->size_low,
758 req->protect, req->handle, name )))
760 int access = FILE_MAP_ALL_ACCESS;
761 if (!(req->protect & VPROT_WRITE)) access &= ~FILE_MAP_WRITE;
762 reply.handle = alloc_handle( current->process, obj, access, req->inherit );
763 release_object( obj );
765 send_reply( current, -1, 1, &reply, sizeof(reply) );
768 /* get a mapping information */
769 DECL_HANDLER(get_mapping_info)
771 struct get_mapping_info_reply reply;
772 int map_fd = get_mapping_info( req->handle, &reply );
773 send_reply( current, map_fd, 1, &reply, sizeof(reply) );
776 /* create a device */
777 DECL_HANDLER(create_device)
779 struct object *obj;
780 struct create_device_reply reply = { -1 };
782 if ((obj = create_device( req->id )))
784 reply.handle = alloc_handle( current->process, obj,
785 req->access, req->inherit );
786 release_object( obj );
788 send_reply( current, -1, 1, &reply, sizeof(reply) );
791 /* create a snapshot */
792 DECL_HANDLER(create_snapshot)
794 struct object *obj;
795 struct create_snapshot_reply reply = { -1 };
797 if ((obj = create_snapshot( req->flags )))
799 reply.handle = alloc_handle( current->process, obj, 0, req->inherit );
800 release_object( obj );
802 send_reply( current, -1, 1, &reply, sizeof(reply) );
805 /* get the next process from a snapshot */
806 DECL_HANDLER(next_process)
808 struct next_process_reply reply;
809 snapshot_next_process( req->handle, req->reset, &reply );
810 send_reply( current, -1, 1, &reply, sizeof(reply) );