Added server snapshot support (processes only for now).
[wine] / server / request.c
1 /*
2  * Server-side request handling
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <stdarg.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/types.h>
12 #include <sys/uio.h>
13 #include <unistd.h>
14
15 #include "winerror.h"
16 #include "winnt.h"
17 #include "winbase.h"
18 #include "wincon.h"
19 #define WANT_REQUEST_HANDLERS
20 #include "server.h"
21 #include "server/request.h"
22 #include "server/process.h"
23 #include "server/thread.h"
24
25 /* check that the string is NULL-terminated and that the len is correct */
26 #define CHECK_STRING(func,str,len) \
27   do { if (((str)[(len)-1] || strlen(str) != (len)-1)) \
28          fatal_protocol_error( "%s: invalid string '%.*s'\n", (func), (len), (str) ); \
29      } while(0)
30  
31 struct thread *current = NULL;  /* thread handling the current request */
32
33 /* complain about a protocol error and terminate the client connection */
34 static void fatal_protocol_error( const char *err, ... )
35 {
36     va_list args;
37
38     va_start( args, err );
39     fprintf( stderr, "Protocol error:%p: ", current );
40     vfprintf( stderr, err, args );
41     va_end( args );
42     remove_client( current->client_fd, -2 );
43 }
44
45 /* call a request handler */
46 void call_req_handler( struct thread *thread, enum request req,
47                        void *data, int len, int fd )
48 {
49     const struct handler *handler = &req_handlers[req];
50     char *ptr;
51
52     current = thread;
53     if ((req < 0) || (req >= REQ_NB_REQUESTS))
54     {
55         fatal_protocol_error( "unknown request %d\n", req );
56         return;
57     }
58
59     if (len < handler->min_size)
60     {
61         fatal_protocol_error( "req %d bad length %d < %d)\n", req, len, handler->min_size );
62         return;
63     }
64
65     /* now call the handler */
66     if (current)
67     {
68         CLEAR_ERROR();
69         if (debug_level) trace_request( req, data, len, fd );
70     }
71     len -= handler->min_size;
72     ptr = (char *)data + handler->min_size;
73     handler->handler( data, ptr, len, fd );
74     current = NULL;
75 }
76
77 /* handle a client timeout (unused for now) */
78 void call_timeout_handler( struct thread *thread )
79 {
80     current = thread;
81     if (debug_level) trace_timeout();
82     CLEAR_ERROR();
83     thread_timeout();
84     current = NULL;
85 }
86
87 /* a thread has been killed */
88 void call_kill_handler( struct thread *thread, int exit_code )
89 {
90     /* must be reentrant WRT call_req_handler */
91     struct thread *old_current = current;
92     current = thread;
93     if (current)
94     {
95         if (debug_level) trace_kill( exit_code );
96         thread_killed( current, exit_code );
97     }
98     current = (old_current != thread) ? old_current : NULL;
99 }
100
101
102 /* create a new thread */
103 DECL_HANDLER(new_thread)
104 {
105     struct new_thread_reply reply;
106     struct thread *new_thread;
107     int new_fd, err;
108
109     if ((new_fd = dup(fd)) == -1)
110     {
111         new_thread = NULL;
112         err = ERROR_TOO_MANY_OPEN_FILES;
113         goto done;
114     }
115     if (!(new_thread = create_thread( new_fd, req->pid, &reply.thandle,
116                                       &reply.phandle )))
117     {
118         close( new_fd );
119         err = ERROR_OUTOFMEMORY;
120         goto done;
121     }
122     reply.tid = new_thread;
123     reply.pid = new_thread->process;
124     err = ERROR_SUCCESS;
125
126  done:
127     if (!current)
128     {
129         /* first client doesn't have a current */
130         struct iovec vec = { &reply, sizeof(reply) };
131         send_reply_v( get_initial_client_fd(), err, -1, &vec, 1 );
132     }
133     else
134     {
135         SET_ERROR( err );
136         send_reply( current, -1, 1, &reply, sizeof(reply) );
137     }
138 }
139
140 /* create a new thread */
141 DECL_HANDLER(init_thread)
142 {
143     if (current->state != STARTING)
144     {
145         fatal_protocol_error( "init_thread: already running\n" );
146         return;
147     }
148     current->state    = RUNNING;
149     current->unix_pid = req->unix_pid;
150     if (!(current->name = mem_alloc( len + 1 ))) goto done;
151     memcpy( current->name, data, len );
152     current->name[len] = '\0';
153     CLEAR_ERROR();
154  done:
155     send_reply( current, -1, 0 );
156 }
157
158 /* set the debug level */
159 DECL_HANDLER(set_debug)
160 {
161     debug_level = req->level;
162     /* Make sure last_req is initialized */
163     current->last_req = REQ_SET_DEBUG;
164     CLEAR_ERROR();
165     send_reply( current, -1, 0 );
166 }
167
168 /* terminate a process */
169 DECL_HANDLER(terminate_process)
170 {
171     struct process *process;
172
173     if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
174     {
175         kill_process( process, req->exit_code );
176         release_object( process );
177     }
178     if (current) send_reply( current, -1, 0 );
179 }
180
181 /* terminate a thread */
182 DECL_HANDLER(terminate_thread)
183 {
184     struct thread *thread;
185
186     if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE )))
187     {
188         kill_thread( thread, req->exit_code );
189         release_object( thread );
190     }
191     if (current) send_reply( current, -1, 0 );
192 }
193
194 /* close a handle */
195 DECL_HANDLER(close_handle)
196 {
197     close_handle( current->process, req->handle );
198     send_reply( current, -1, 0 );
199 }
200
201 /* duplicate a handle */
202 DECL_HANDLER(dup_handle)
203 {
204     struct dup_handle_reply reply = { -1 };
205     struct process *src, *dst;
206
207     if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
208     {
209         if (req->options & DUP_HANDLE_MAKE_GLOBAL)
210         {
211             reply.handle = duplicate_handle( src, req->src_handle, NULL, -1,
212                                              req->access, req->inherit, req->options );
213         }
214         else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
215         {
216             reply.handle = duplicate_handle( src, req->src_handle, dst, req->dst_handle,
217                                              req->access, req->inherit, req->options );
218             release_object( dst );
219         }
220         /* close the handle no matter what happened */
221         if (req->options & DUP_HANDLE_CLOSE_SOURCE)
222             close_handle( src, req->src_handle );
223         release_object( src );
224     }
225     send_reply( current, -1, 1, &reply, sizeof(reply) );
226 }
227
228 /* fetch information about a process */
229 DECL_HANDLER(get_process_info)
230 {
231     struct process *process;
232     struct get_process_info_reply reply = { 0, 0, 0 };
233
234     if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
235     {
236         get_process_info( process, &reply );
237         release_object( process );
238     }
239     send_reply( current, -1, 1, &reply, sizeof(reply) );
240 }
241
242 /* set information about a process */
243 DECL_HANDLER(set_process_info)
244 {
245     struct process *process;
246
247     if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
248     {
249         set_process_info( process, req );
250         release_object( process );
251     }
252     send_reply( current, -1, 0 );
253 }
254
255 /* fetch information about a thread */
256 DECL_HANDLER(get_thread_info)
257 {
258     struct thread *thread;
259     struct get_thread_info_reply reply = { 0, 0 };
260
261     if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION )))
262     {
263         get_thread_info( thread, &reply );
264         release_object( thread );
265     }
266     send_reply( current, -1, 1, &reply, sizeof(reply) );
267 }
268
269 /* set information about a thread */
270 DECL_HANDLER(set_thread_info)
271 {
272     struct thread *thread;
273
274     if ((thread = get_thread_from_handle( req->handle, THREAD_SET_INFORMATION )))
275     {
276         set_thread_info( thread, req );
277         release_object( thread );
278     }
279     send_reply( current, -1, 0 );
280 }
281
282 /* suspend a thread */
283 DECL_HANDLER(suspend_thread)
284 {
285     struct thread *thread;
286     struct suspend_thread_reply reply = { -1 };
287     if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
288     {
289         reply.count = suspend_thread( thread );
290         release_object( thread );
291     }
292     send_reply( current, -1, 1, &reply, sizeof(reply) );
293     
294 }
295
296 /* resume a thread */
297 DECL_HANDLER(resume_thread)
298 {
299     struct thread *thread;
300     struct resume_thread_reply reply = { -1 };
301     if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
302     {
303         reply.count = resume_thread( thread );
304         release_object( thread );
305     }
306     send_reply( current, -1, 1, &reply, sizeof(reply) );
307     
308 }
309
310 /* queue an APC for a thread */
311 DECL_HANDLER(queue_apc)
312 {
313     struct thread *thread;
314     if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
315     {
316         thread_queue_apc( thread, req->func, req->param );
317         release_object( thread );
318     }
319     send_reply( current, -1, 0 );
320 }
321
322 /* open a handle to a process */
323 DECL_HANDLER(open_process)
324 {
325     struct open_process_reply reply = { -1 };
326     struct process *process = get_process_from_id( req->pid );
327     if (process)
328     {
329         reply.handle = alloc_handle( current->process, process,
330                                      req->access, req->inherit );
331         release_object( process );
332     }
333     send_reply( current, -1, 1, &reply, sizeof(reply) );
334 }
335
336 /* select on a handle list */
337 DECL_HANDLER(select)
338 {
339     if (len != req->count * sizeof(int))
340         fatal_protocol_error( "select: bad length %d for %d handles\n",
341                               len, req->count );
342     sleep_on( current, req->count, (int *)data, req->flags, req->timeout );
343 }
344
345 /* create an event */
346 DECL_HANDLER(create_event)
347 {
348     struct create_event_reply reply = { -1 };
349     struct object *obj;
350     char *name = (char *)data;
351     if (!len) name = NULL;
352     else CHECK_STRING( "create_event", name, len );
353
354     obj = create_event( name, req->manual_reset, req->initial_state );
355     if (obj)
356     {
357         reply.handle = alloc_handle( current->process, obj, EVENT_ALL_ACCESS, req->inherit );
358         release_object( obj );
359     }
360     send_reply( current, -1, 1, &reply, sizeof(reply) );
361 }
362
363 /* do an event operation */
364 DECL_HANDLER(event_op)
365 {
366     switch(req->op)
367     {
368     case PULSE_EVENT:
369         pulse_event( req->handle );
370         break;
371     case SET_EVENT:
372         set_event( req->handle );
373         break;
374     case RESET_EVENT:
375         reset_event( req->handle );
376         break;
377     default:
378         fatal_protocol_error( "event_op: invalid operation %d\n", req->op );
379     }
380     send_reply( current, -1, 0 );
381 }
382
383 /* create a mutex */
384 DECL_HANDLER(create_mutex)
385 {
386     struct create_mutex_reply reply = { -1 };
387     struct object *obj;
388     char *name = (char *)data;
389     if (!len) name = NULL;
390     else CHECK_STRING( "create_mutex", name, len );
391
392     obj = create_mutex( name, req->owned );
393     if (obj)
394     {
395         reply.handle = alloc_handle( current->process, obj, MUTEX_ALL_ACCESS, req->inherit );
396         release_object( obj );
397     }
398     send_reply( current, -1, 1, &reply, sizeof(reply) );
399 }
400
401 /* release a mutex */
402 DECL_HANDLER(release_mutex)
403 {
404     if (release_mutex( req->handle )) CLEAR_ERROR();
405     send_reply( current, -1, 0 );
406 }
407
408 /* create a semaphore */
409 DECL_HANDLER(create_semaphore)
410 {
411     struct create_semaphore_reply reply = { -1 };
412     struct object *obj;
413     char *name = (char *)data;
414     if (!len) name = NULL;
415     else CHECK_STRING( "create_semaphore", name, len );
416
417     obj = create_semaphore( name, req->initial, req->max );
418     if (obj)
419     {
420         reply.handle = alloc_handle( current->process, obj, SEMAPHORE_ALL_ACCESS, req->inherit );
421         release_object( obj );
422     }
423     send_reply( current, -1, 1, &reply, sizeof(reply) );
424 }
425
426 /* release a semaphore */
427 DECL_HANDLER(release_semaphore)
428 {
429     struct release_semaphore_reply reply;
430     if (release_semaphore( req->handle, req->count, &reply.prev_count )) CLEAR_ERROR();
431     send_reply( current, -1, 1, &reply, sizeof(reply) );
432 }
433
434 /* open a handle to a named object (event, mutex, semaphore) */
435 DECL_HANDLER(open_named_obj)
436 {
437     struct open_named_obj_reply reply;
438     char *name = (char *)data;
439     if (!len) name = NULL;
440     else CHECK_STRING( "open_named_obj", name, len );
441
442     switch(req->type)
443     {
444     case OPEN_EVENT:
445         reply.handle = open_event( req->access, req->inherit, name );
446         break;
447     case OPEN_MUTEX:
448         reply.handle = open_mutex( req->access, req->inherit, name );
449         break;
450     case OPEN_SEMAPHORE:
451         reply.handle = open_semaphore( req->access, req->inherit, name );
452         break;
453     case OPEN_MAPPING:
454         reply.handle = open_mapping( req->access, req->inherit, name );
455         break;
456     default:
457         fatal_protocol_error( "open_named_obj: invalid type %d\n", req->type );
458     }
459     send_reply( current, -1, 1, &reply, sizeof(reply) );
460 }
461
462 /* create a file */
463 DECL_HANDLER(create_file)
464 {
465     struct create_file_reply reply = { -1 };
466     struct object *obj;
467     char *name = (char *)data;
468     if (!len) name = NULL;
469     else CHECK_STRING( "create_file", name, len );
470
471     if ((obj = create_file( fd, name, req->access,
472                             req->sharing, req->create, req->attrs )) != NULL)
473     {
474         reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
475         release_object( obj );
476     }
477     send_reply( current, -1, 1, &reply, sizeof(reply) );
478 }
479
480 /* get a Unix fd to read from a file */
481 DECL_HANDLER(get_read_fd)
482 {
483     struct object *obj;
484     int read_fd;
485
486     if ((obj = get_handle_obj( current->process, req->handle, GENERIC_READ, NULL )))
487     {
488         read_fd = obj->ops->get_read_fd( obj );
489         release_object( obj );
490     }
491     else read_fd = -1;
492     send_reply( current, read_fd, 0 );
493 }
494
495 /* get a Unix fd to write to a file */
496 DECL_HANDLER(get_write_fd)
497 {
498     struct object *obj;
499     int write_fd;
500
501     if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
502     {
503         write_fd = obj->ops->get_write_fd( obj );
504         release_object( obj );
505     }
506     else write_fd = -1;
507     send_reply( current, write_fd, 0 );
508 }
509
510 /* set a file current position */
511 DECL_HANDLER(set_file_pointer)
512 {
513     struct set_file_pointer_reply reply = { req->low, req->high };
514     set_file_pointer( req->handle, &reply.low, &reply.high, req->whence );
515     send_reply( current, -1, 1, &reply, sizeof(reply) );
516 }
517
518 /* truncate (or extend) a file */
519 DECL_HANDLER(truncate_file)
520 {
521     truncate_file( req->handle );
522     send_reply( current, -1, 0 );
523 }
524
525 /* flush a file buffers */
526 DECL_HANDLER(flush_file)
527 {
528     struct object *obj;
529
530     if ((obj = get_handle_obj( current->process, req->handle, GENERIC_WRITE, NULL )))
531     {
532         obj->ops->flush( obj );
533         release_object( obj );
534     }
535     send_reply( current, -1, 0 );
536 }
537
538 /* set a file access and modification times */
539 DECL_HANDLER(set_file_time)
540 {
541     set_file_time( req->handle, req->access_time, req->write_time );
542     send_reply( current, -1, 0 );
543 }
544
545 /* get a file information */
546 DECL_HANDLER(get_file_info)
547 {
548     struct object *obj;
549     struct get_file_info_reply reply;
550
551     if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
552     {
553         obj->ops->get_file_info( obj, &reply );
554         release_object( obj );
555     }
556     send_reply( current, -1, 1, &reply, sizeof(reply) );
557 }
558
559 /* lock a region of a file */
560 DECL_HANDLER(lock_file)
561 {
562     struct file *file;
563
564     if ((file = get_file_obj( current->process, req->handle, 0 )))
565     {
566         file_lock( file, req->offset_high, req->offset_low,
567                    req->count_high, req->count_low );
568         release_object( file );
569     }
570     send_reply( current, -1, 0 );
571 }
572
573
574 /* unlock a region of a file */
575 DECL_HANDLER(unlock_file)
576 {
577     struct file *file;
578
579     if ((file = get_file_obj( current->process, req->handle, 0 )))
580     {
581         file_unlock( file, req->offset_high, req->offset_low,
582                      req->count_high, req->count_low );
583         release_object( file );
584     }
585     send_reply( current, -1, 0 );
586 }
587
588
589 /* create an anonymous pipe */
590 DECL_HANDLER(create_pipe)
591 {
592     struct create_pipe_reply reply = { -1, -1 };
593     struct object *obj[2];
594     if (create_pipe( obj ))
595     {
596         reply.handle_read = alloc_handle( current->process, obj[0],
597                                           STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
598                                           req->inherit );
599         if (reply.handle_read != -1)
600         {
601             reply.handle_write = alloc_handle( current->process, obj[1],
602                                                STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
603                                                req->inherit );
604             if (reply.handle_write == -1)
605                 close_handle( current->process, reply.handle_read );
606         }
607         release_object( obj[0] );
608         release_object( obj[1] );
609     }
610     send_reply( current, -1, 1, &reply, sizeof(reply) );
611 }
612
613 /* allocate a console for the current process */
614 DECL_HANDLER(alloc_console)
615 {
616     alloc_console( current->process );
617     send_reply( current, -1, 0 );
618 }
619
620 /* free the console of the current process */
621 DECL_HANDLER(free_console)
622 {
623     free_console( current->process );
624     send_reply( current, -1, 0 );
625 }
626
627 /* open a handle to the process console */
628 DECL_HANDLER(open_console)
629 {
630     struct object *obj;
631     struct open_console_reply reply = { -1 };
632     if ((obj = get_console( current->process, req->output )))
633     {
634         reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
635         release_object( obj );
636     }
637     send_reply( current, -1, 1, &reply, sizeof(reply) );
638 }
639
640 /* set info about a console (output only) */
641 DECL_HANDLER(set_console_info)
642 {
643     char *name = (char *)data;
644     if (!len) name = NULL;
645     else CHECK_STRING( "set_console_info", name, len );
646     set_console_info( req->handle, req, name );
647     send_reply( current, -1, 0 );
648 }
649
650 /* get info about a console (output only) */
651 DECL_HANDLER(get_console_info)
652 {
653     struct get_console_info_reply reply;
654     const char *title;
655     get_console_info( req->handle, &reply, &title );
656     send_reply( current, -1, 2, &reply, sizeof(reply),
657                 title, title ? strlen(title)+1 : 0 );
658 }
659
660 /* set a console fd */
661 DECL_HANDLER(set_console_fd)
662 {
663     set_console_fd( req->handle, fd, req->pid );
664     send_reply( current, -1, 0 );
665 }
666
667 /* get a console mode (input or output) */
668 DECL_HANDLER(get_console_mode)
669 {
670     struct get_console_mode_reply reply;
671     get_console_mode( req->handle, &reply.mode );
672     send_reply( current, -1, 1, &reply, sizeof(reply) );
673 }
674
675 /* set a console mode (input or output) */
676 DECL_HANDLER(set_console_mode)
677 {
678     set_console_mode( req->handle, req->mode );
679     send_reply( current, -1, 0 );
680 }
681
682 /* add input records to a console input queue */
683 DECL_HANDLER(write_console_input)
684 {
685     struct write_console_input_reply reply;
686     INPUT_RECORD *records = (INPUT_RECORD *)data;
687
688     if (len != req->count * sizeof(INPUT_RECORD))
689         fatal_protocol_error( "write_console_input: bad length %d for %d records\n",
690                               len, req->count );
691     reply.written = write_console_input( req->handle, req->count, records );
692     send_reply( current, -1, 1, &reply, sizeof(reply) );
693 }
694
695 /* fetch input records from a console input queue */
696 DECL_HANDLER(read_console_input)
697 {
698     read_console_input( req->handle, req->count, req->flush );
699 }
700
701 /* create a change notification */
702 DECL_HANDLER(create_change_notification)
703 {
704     struct object *obj;
705     struct create_change_notification_reply reply = { -1 };
706
707     if ((obj = create_change_notification( req->subtree, req->filter )))
708     {
709         reply.handle = alloc_handle( current->process, obj,
710                                      STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
711         release_object( obj );
712     }
713     send_reply( current, -1, 1, &reply, sizeof(reply) );
714 }
715
716 /* create a file mapping */
717 DECL_HANDLER(create_mapping)
718 {
719     struct object *obj;
720     struct create_mapping_reply reply = { -1 };
721     char *name = (char *)data;
722     if (!len) name = NULL;
723     else CHECK_STRING( "create_mapping", name, len );
724
725     if ((obj = create_mapping( req->size_high, req->size_low,
726                                req->protect, req->handle, name )))
727     {
728         int access = FILE_MAP_ALL_ACCESS;
729         if (!(req->protect & VPROT_WRITE)) access &= ~FILE_MAP_WRITE;
730         reply.handle = alloc_handle( current->process, obj, access, 0 );
731         release_object( obj );
732     }
733     send_reply( current, -1, 1, &reply, sizeof(reply) );
734 }
735
736 /* get a mapping information */
737 DECL_HANDLER(get_mapping_info)
738 {
739     struct get_mapping_info_reply reply;
740     int map_fd = get_mapping_info( req->handle, &reply );
741     send_reply( current, map_fd, 1, &reply, sizeof(reply) );
742 }
743
744 /* create a device */
745 DECL_HANDLER(create_device)
746 {
747     struct object *obj;
748     struct create_device_reply reply = { -1 };
749
750     if ((obj = create_device( req->id )))
751     {
752         reply.handle = alloc_handle( current->process, obj,
753                                      req->access, req->inherit );
754         release_object( obj );
755     }
756     send_reply( current, -1, 1, &reply, sizeof(reply) );
757 }
758
759 /* create a snapshot */
760 DECL_HANDLER(create_snapshot)
761 {
762     struct object *obj;
763     struct create_snapshot_reply reply = { -1 };
764
765     if ((obj = create_snapshot( req->flags )))
766     {
767         reply.handle = alloc_handle( current->process, obj, 0, req->inherit );
768         release_object( obj );
769     }
770     send_reply( current, -1, 1, &reply, sizeof(reply) );
771 }
772
773 /* get the next process from a snapshot */
774 DECL_HANDLER(next_process)
775 {
776     struct next_process_reply reply;
777     snapshot_next_process( req->handle, req->reset, &reply );
778     send_reply( current, -1, 1, &reply, sizeof(reply) );
779 }
780