Copy wininet to branch
[reactos.git] / reactos / tools / widl / server.c
1 /*
2 * IDL Compiler
3 *
4 * Copyright 2005 Eric Kohl
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif
28 #include <string.h>
29 #include <assert.h>
30 #include <ctype.h>
31 #include <signal.h>
32
33 #include "widl.h"
34 #include "utils.h"
35 #include "parser.h"
36 #include "header.h"
37
38 #define END_OF_LIST(list) \
39 do { \
40 if (list) { \
41 while (NEXT_LINK(list)) \
42 list = NEXT_LINK(list); \
43 } \
44 } while(0)
45
46 static FILE* server;
47 static int indent = 0;
48
49
50 static int print_server(const char *format, ...)
51 {
52 va_list va;
53 int i, r;
54
55 va_start(va, format);
56 for (i = 0; i < indent; i++)
57 fprintf(server, " ");
58 r = vfprintf(server, format, va);
59 va_end(va);
60 return r;
61 }
62
63
64 static unsigned char
65 get_base_type(unsigned char type)
66 {
67
68 switch (type)
69 {
70 case RPC_FC_USHORT:
71 type = RPC_FC_SHORT;
72 break;
73
74 case RPC_FC_ULONG:
75 type = RPC_FC_LONG;
76 break;
77 }
78
79 return type;
80 }
81
82
83 static void write_procformatstring(type_t *iface)
84 {
85 func_t *func = iface->funcs;
86 var_t *var;
87 unsigned int type_offset = 2;
88 int in_attr, out_attr;
89
90 print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
91 print_server("{\n");
92 indent++;
93 print_server("0,\n");
94 print_server("{\n");
95 indent++;
96
97 while (NEXT_LINK(func)) func = NEXT_LINK(func);
98 while (func)
99 {
100 /* emit argument data */
101 if (func->args)
102 {
103 var = func->args;
104 while (NEXT_LINK(var)) var = NEXT_LINK(var);
105 while (var)
106 {
107 out_attr = is_attr(var->attrs, ATTR_OUT);
108 in_attr = is_attr(var->attrs, ATTR_IN);
109
110 /* set 'in' attribute if neither 'in' nor 'out' is set */
111 if (!out_attr && !in_attr)
112 in_attr = 1;
113
114 if (var->ptr_level == 0)
115 {
116 if (is_base_type(var->type))
117 {
118 print_server("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
119 print_server("0x%02x, /* FC_<type> */\n", get_base_type(var->type->type));
120 }
121 else
122 {
123 error("%s:%d Unknown/unsupported type 0x%x\n",
124 __FUNCTION__,__LINE__, var->type->type);
125 return;
126 }
127 }
128 else if (var->ptr_level == 1)
129 {
130 if (is_base_type(var->type))
131 {
132 if (in_attr & !out_attr)
133 print_server("0x4d, /* FC_IN_PARAM */\n");
134 else if (!in_attr & out_attr)
135 print_server("0x51, /* FC_OUT_PARAM */\n");
136 else if (in_attr & out_attr)
137 print_server("0x50, /* FC_IN_OUT_PARAM */\n");
138 fprintf(server, "#ifndef _ALPHA_\n");
139 print_server("0x01,\n");
140 fprintf(server, "#else\n");
141 print_server("0x02,\n");
142 fprintf(server, "#endif\n");
143 print_server("NdrFcShort(0x%x),\n", type_offset);
144 type_offset += 4;
145 }
146 else
147 {
148 error("%s:%d Unknown/unsupported type 0x%x\n",
149 __FUNCTION__,__LINE__, var->type->type);
150 return;
151 }
152 }
153
154 var = PREV_LINK(var);
155 }
156 }
157
158 /* emit return value data */
159 var = func->def;
160 if (is_void(var->type, NULL))
161 {
162 print_server("0x5b, /* FC_END */\n");
163 print_server("0x5c, /* FC_PAD */\n");
164 }
165 else if (is_base_type(var->type))
166 {
167 print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
168 print_server("0x%02x, /* FC_<type> */\n", get_base_type(var->type->type));
169 }
170 else
171 {
172 error("%s:%d Unknown/unsupported type 0x%x\n",
173 __FUNCTION__,__LINE__, var->type->type);
174 return;
175 }
176
177 func = PREV_LINK(func);
178 }
179
180 print_server("0x0\n");
181 indent--;
182 print_server("}\n");
183 indent--;
184 print_server("};\n");
185 print_server("\n");
186 }
187
188
189 static void write_typeformatstring(type_t *iface)
190 {
191 func_t *func = iface->funcs;
192 var_t *var;
193 int out_attr;
194 int string_attr;
195 int ptr_attr, ref_attr, unique_attr;
196
197 print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
198 print_server("{\n");
199 indent++;
200 print_server("0,\n");
201 print_server("{\n");
202 indent++;
203 print_server("NdrFcShort(0x0),\n");
204
205 while (NEXT_LINK(func)) func = NEXT_LINK(func);
206 while (func)
207 {
208 if (func->args)
209 {
210 var = func->args;
211 while (NEXT_LINK(var)) var = NEXT_LINK(var);
212 while (var)
213 {
214 out_attr = is_attr(var->attrs, ATTR_OUT);
215 string_attr = is_attr(var->attrs, ATTR_STRING);
216
217 if (var->ptr_level > 1)
218 {
219 error("Function '%s' argument '%s': Pointer level %d not supported!\n",
220 func->def->name, var->name, var->ptr_level);
221 return;
222 }
223
224 if (var->ptr_level == 1)
225 {
226 ptr_attr = is_attr(var->attrs, ATTR_PTR);
227 ref_attr = is_attr(var->attrs, ATTR_REF);
228 unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
229
230 if (ptr_attr + ref_attr + unique_attr == 0)
231 ref_attr = 1;
232
233 if (is_base_type(var->type))
234 {
235 if (out_attr)
236 print_server("0x11, 0x0c, /* FC_RP [allocated_on_stack] [simple_pointer] */\n");
237 else
238 {
239 if (ptr_attr)
240 print_server("0x14, 0x08, /* FC_FP [simple_pointer] */\n");
241 else if (ref_attr)
242 print_server("0x11, 0x08, /* FC_RP [simple_pointer] */\n");
243 else if (unique_attr)
244 print_server("0x12, 0x08, /* FC_UP [simple_pointer] */\n");
245 }
246
247 if (string_attr)
248 {
249 if (var->type->type == RPC_FC_CHAR)
250 print_server("0x%02x, /* FC_C_CSTRING */\n", RPC_FC_C_CSTRING);
251 else if (var->type->type == RPC_FC_WCHAR)
252 print_server("0x%02x, /* FC_C_WSTRING */\n", RPC_FC_C_WSTRING);
253 else
254 {
255 error("%s: Invalid type!\n", __FUNCTION__);
256 return;
257 }
258 }
259 else
260 print_server("0x%02x, /* FC_<type> */\n", get_base_type(var->type->type));
261 print_server("0x5c, /* FC_PAD */\n");
262 }
263 }
264
265 var = PREV_LINK(var);
266 }
267 }
268
269
270
271 func = PREV_LINK(func);
272 }
273
274 print_server("0x0\n");
275 indent--;
276 print_server("}\n");
277 indent--;
278 print_server("};\n");
279 print_server("\n");
280 }
281
282
283 static void print_message_buffer_size(func_t *func)
284 {
285 unsigned int alignment = 0;
286 int size = 0;
287 int last_size = -1;
288 int in_attr;
289 int out_attr;
290 int string_attr;
291 int empty_line;
292 var_t *var;
293
294 fprintf(server, "\n");
295 print_server("_StubMsg.BufferLength =");
296 if (func->args)
297 {
298 var = func->args;
299 while (NEXT_LINK(var)) var = NEXT_LINK(var);
300 for (; var; var = PREV_LINK(var))
301 {
302 out_attr = is_attr(var->attrs, ATTR_OUT);
303 if (!out_attr)
304 continue;
305
306 alignment = 0;
307 switch (var->type->type)
308 {
309 case RPC_FC_BYTE:
310 case RPC_FC_CHAR:
311 case RPC_FC_SMALL:
312 size = 1;
313 alignment = 0;
314 break;
315
316 case RPC_FC_WCHAR:
317 case RPC_FC_USHORT:
318 case RPC_FC_SHORT:
319 size = 2;
320 if (last_size > 0 && last_size < 2)
321 alignment += (2 - last_size);
322 break;
323
324 case RPC_FC_ULONG:
325 case RPC_FC_LONG:
326 case RPC_FC_FLOAT:
327 size = 4;
328 if (last_size > 0 && last_size < 4)
329 alignment += (4 - last_size);
330 break;
331
332 case RPC_FC_HYPER:
333 case RPC_FC_DOUBLE:
334 size = 8;
335 if (last_size > 0 && last_size < 4)
336 alignment += (4 - last_size);
337 break;
338
339 default:
340 error("%s:%d Unknown/unsupported type 0x%x\n",
341 __FUNCTION__,__LINE__, var->type->type);
342 return;
343 }
344
345 if (last_size != -1)
346 fprintf(server, " +");
347 fprintf(server, " %dU", (size == 0) ? 0 : size + alignment);
348
349 last_size = size;
350 }
351 }
352
353 /* return value size */
354 if (!is_void(func->def->type, NULL))
355 {
356 switch(func->def->type->type)
357 {
358 case RPC_FC_BYTE:
359 case RPC_FC_SMALL:
360 case RPC_FC_CHAR:
361 case RPC_FC_WCHAR:
362 case RPC_FC_USHORT:
363 case RPC_FC_SHORT:
364 case RPC_FC_ULONG:
365 case RPC_FC_LONG:
366 case RPC_FC_FLOAT:
367 size = 4;
368 if (last_size > 0 && last_size < 4)
369 alignment += (4 - last_size);
370 break;
371
372 case RPC_FC_HYPER:
373 case RPC_FC_DOUBLE:
374 size = 8;
375 if (last_size > 0 && last_size < 4)
376 alignment += (4 - last_size);
377 break;
378
379 default:
380 error("%s:%d Unknown/unsupported type 0x%x\n",
381 __FUNCTION__,__LINE__, func->def->type->type);
382 return;
383 }
384
385 if (last_size != -1)
386 fprintf(server, " +");
387
388 fprintf(server, " %dU", (size == 0) ? 0 : size + alignment);
389 }
390 fprintf(server, ";\n");
391
392 /* get string size */
393 if (func->args)
394 {
395 empty_line = 0;
396 var = func->args;
397 while (NEXT_LINK(var)) var = NEXT_LINK(var);
398 for (; var; var = PREV_LINK(var))
399 {
400 out_attr = is_attr(var->attrs, ATTR_OUT);
401 in_attr = is_attr(var->attrs, ATTR_IN);
402 string_attr = is_attr(var->attrs, ATTR_STRING);
403
404 /* set 'in' attribute if neither 'in' nor 'out' is found */
405 if (!out_attr && !in_attr)
406 in_attr = 1;
407
408 if (var->ptr_level == 1 &&
409 string_attr &&
410 (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
411 {
412 print_server("_StubMsg.BufferLength += 16;\n");
413 empty_line = 1;
414 }
415 }
416
417 if (empty_line)
418 fprintf(server, "\n");
419 }
420 }
421
422
423 static void init_pointers (func_t *func)
424 {
425 var_t *var;
426
427 if (!func->args)
428 return;
429
430 var = func->args;
431 while (NEXT_LINK(var)) var = NEXT_LINK(var);
432 while (var)
433 {
434 if (var->ptr_level == 1)
435 {
436 print_server("(");
437 write_type(server, var->type, NULL, var->tname);
438 fprintf(server, " __RPC_FAR *)%s = 0;\n", var->name);
439 }
440 else if (var->ptr_level > 1)
441 {
442 error("Pointer level %d not supported!\n", var->ptr_level);
443 return;
444 }
445
446 var = PREV_LINK(var);
447 }
448 fprintf(server, "\n");
449 }
450
451
452 static void unmarshall_in_arguments(func_t *func, unsigned int *type_offset)
453 {
454 unsigned int alignment;
455 unsigned int size;
456 unsigned int last_size = 0;
457 var_t *var;
458 int in_attr, out_attr;
459 int string_attr;
460 int ptr_attr, ref_attr, unique_attr;
461
462 if (!func->args)
463 return;
464
465 var = func->args;
466 while (NEXT_LINK(var)) var = NEXT_LINK(var);
467 for (; var; var = PREV_LINK(var))
468 {
469 out_attr = is_attr(var->attrs, ATTR_OUT);
470 in_attr = is_attr(var->attrs, ATTR_IN);
471 string_attr = is_attr(var->attrs, ATTR_STRING);
472
473 /* set 'in' attribute if neither 'in' nor 'out' is set */
474 if (!out_attr && !in_attr)
475 in_attr = 1;
476
477 if (in_attr)
478 {
479 if (var->ptr_level == 1)
480 {
481 ptr_attr = is_attr(var->attrs, ATTR_PTR);
482 ref_attr = is_attr(var->attrs, ATTR_REF);
483 unique_attr = is_attr(var->attrs, ATTR_UNIQUE);
484 if (ptr_attr + ref_attr + unique_attr == 0)
485 ref_attr = 1;
486
487 if (ref_attr)
488 {
489 if (string_attr &&
490 (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))
491 {
492 print_server("NdrConformantStringUnmarshall(\n");
493 indent++;
494 print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
495 print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);
496 print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n", *type_offset + 2);
497 print_server("(unsigned char)0);\n");
498 indent--;
499 fprintf(server, "\n");
500 }
501 else
502 {
503 alignment = 0;
504 switch (var->type->type)
505 {
506 case RPC_FC_BYTE:
507 case RPC_FC_CHAR:
508 case RPC_FC_SMALL:
509 size = 1;
510 alignment = 0;
511 break;
512
513 case RPC_FC_WCHAR:
514 case RPC_FC_USHORT:
515 case RPC_FC_SHORT:
516 size = 2;
517 if (last_size != 0 && last_size < 2)
518 alignment = (2 - last_size);
519 break;
520
521 case RPC_FC_ULONG:
522 case RPC_FC_LONG:
523 case RPC_FC_FLOAT:
524 size = 4;
525 if (last_size != 0 && last_size < 4)
526 alignment = (4 - last_size);
527 break;
528
529 case RPC_FC_HYPER:
530 case RPC_FC_DOUBLE:
531 size = 8;
532 if (last_size != 0 && last_size < 4)
533 alignment = (4 - last_size);
534 break;
535
536 case RPC_FC_IGNORE:
537 size = 0;
538 break;
539
540 default:
541 error("%s:%d Unknown/unsupported type 0x%x\n",
542 __FUNCTION__,__LINE__, var->type->type);
543 return;
544 }
545
546 if (size != 0)
547 {
548 if (alignment != 0)
549 print_server("_StubMsg.Buffer += %u;\n", alignment);
550
551 print_server("");
552 write_name(server, var);
553 fprintf(server, " = (");
554 write_type(server, var->type, NULL, var->tname);
555 fprintf(server, " __RPC_FAR*)_StubMsg.Buffer;\n");
556 print_server("_StubMsg.Buffer += sizeof(");
557 write_type(server, var->type, NULL, var->tname);
558 fprintf(server, ");\n");
559 fprintf(server, "\n");
560
561 last_size = size;
562 }
563 }
564 }
565 else if (unique_attr)
566 {
567 print_server("NdrPointerUnmarshall(\n");
568 indent++;
569 print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
570 print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);
571 print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n", *type_offset);
572 print_server("(unsigned char)0);\n");
573 indent--;
574 fprintf(server, "\n");
575 }
576
577 }
578 else
579 {
580 alignment = 0;
581 switch (var->type->type)
582 {
583 case RPC_FC_BYTE:
584 case RPC_FC_CHAR:
585 case RPC_FC_SMALL:
586 size = 1;
587 alignment = 0;
588 break;
589
590 case RPC_FC_WCHAR:
591 case RPC_FC_USHORT:
592 case RPC_FC_SHORT:
593 size = 2;
594 if (last_size != 0 && last_size < 2)
595 alignment = (2 - last_size);
596 break;
597
598 case RPC_FC_ULONG:
599 case RPC_FC_LONG:
600 case RPC_FC_FLOAT:
601 size = 4;
602 if (last_size != 0 && last_size < 4)
603 alignment = (4 - last_size);
604 break;
605
606 case RPC_FC_HYPER:
607 case RPC_FC_DOUBLE:
608 size = 8;
609 if (last_size != 0 && last_size < 4)
610 alignment = (4 - last_size);
611 break;
612
613 case RPC_FC_IGNORE:
614 size = 0;
615 break;
616
617 default:
618 error("%s:%d Unknown/unsupported type 0x%x\n",
619 __FUNCTION__,__LINE__, var->type->type);
620 return;
621 }
622
623 if (size != 0)
624 {
625 if (alignment != 0)
626 print_server("_StubMsg.Buffer += %u;\n", alignment);
627
628 print_server("");
629 write_name(server, var);
630 fprintf(server, " = *((");
631 write_type(server, var->type, NULL, var->tname);
632 fprintf(server, " __RPC_FAR*)_StubMsg.Buffer);\n");
633 print_server("_StubMsg.Buffer += sizeof(");
634 write_type(server, var->type, NULL, var->tname);
635 fprintf(server, ");\n");
636 fprintf(server, "\n");
637
638 last_size = size;
639 }
640 }
641 }
642
643 /* calculate the next type offset */
644 if (var->ptr_level == 1)
645 {
646 *type_offset += 4;
647 }
648 }
649 }
650
651
652 static void marshall_out_arguments(func_t *func)
653 {
654 unsigned int alignment = 0;
655 unsigned int size = 0;
656 unsigned int last_size = 0;
657 var_t *var;
658 var_t *def;
659 int out_attr;
660
661 def = func->def;
662
663 /* marshall the out arguments */
664 if (func->args)
665 {
666 var = func->args;
667 while (NEXT_LINK(var)) var = NEXT_LINK(var);
668 for (; var; var = PREV_LINK(var))
669 {
670 out_attr = is_attr(var->attrs, ATTR_OUT);
671 if (!out_attr)
672 continue;
673
674 alignment = 0;
675 switch (var->type->type)
676 {
677 case RPC_FC_BYTE:
678 case RPC_FC_CHAR:
679 case RPC_FC_SMALL:
680 size = 1;
681 alignment = 0;
682 break;
683
684 case RPC_FC_WCHAR:
685 case RPC_FC_USHORT:
686 case RPC_FC_SHORT:
687 size = 2;
688 if (last_size != 0 && last_size < 2)
689 alignment = (2 - last_size);
690 break;
691
692 case RPC_FC_ULONG:
693 case RPC_FC_LONG:
694 case RPC_FC_FLOAT:
695 size = 4;
696 if (last_size != 0 && last_size < 4)
697 alignment = (4 - last_size);
698 break;
699
700 case RPC_FC_HYPER:
701 case RPC_FC_DOUBLE:
702 size = 8;
703 if (last_size != 0 && last_size < 4)
704 alignment = (4 - last_size);
705 break;
706
707 case RPC_FC_IGNORE:
708 size = 0;
709 break;
710
711 default:
712 error("%s:%d Unknown/unsupported type 0x%x\n",
713 __FUNCTION__,__LINE__, var->type->type);
714 return;
715 }
716
717 if (size != 0)
718 {
719 if (alignment != 0)
720 print_server("_StubMsg.Buffer += %u;\n", alignment);
721
722 if (var->ptr_level == 1)
723 {
724 fprintf(server, "\n");
725 print_server("*((");
726 write_type(server, var->type, NULL, var->tname);
727 fprintf(server, " __RPC_FAR *)_StubMsg.Buffer) = *");
728 write_name(server, var);
729 fprintf(server, ";\n");
730
731 print_server("_StubMsg.Buffer += sizeof(");
732 write_type(server, var->type, NULL, var->tname);
733 fprintf(server, ");");
734 }
735 else
736 {
737 error("Pointer level %d is not supported!\n", var->ptr_level);
738 return;
739 }
740
741 last_size = size;
742 }
743 }
744 }
745
746 /* marshall the return value */
747 if (!is_void(def->type, NULL))
748 {
749 alignment = 0;
750 switch (def->type->type)
751 {
752 case RPC_FC_BYTE:
753 case RPC_FC_CHAR:
754 case RPC_FC_SMALL:
755 case RPC_FC_WCHAR:
756 case RPC_FC_USHORT:
757 case RPC_FC_SHORT:
758 case RPC_FC_ULONG:
759 case RPC_FC_LONG:
760 case RPC_FC_FLOAT:
761 size = 4;
762 if (last_size != 0 && last_size < 4)
763 alignment = (4 - last_size);
764 break;
765
766 case RPC_FC_HYPER:
767 case RPC_FC_DOUBLE:
768 size = 8;
769 if (last_size != 0 && last_size < 4)
770 alignment = (4 - last_size);
771 break;
772
773 default:
774 error("%s:%d Unknown/unsupported type 0x%x\n",
775 __FUNCTION__,__LINE__, var->type->type);
776 return;
777 }
778
779 fprintf(server, "\n");
780 if (alignment != 0)
781 print_server("_StubMsg.Buffer += %u;\n", alignment);
782 print_server("*((");
783 write_type(server, def->type, def, def->tname);
784 fprintf(server, " __RPC_FAR *)_StubMsg.Buffer) = _RetVal;\n");
785 print_server("_StubMsg.Buffer += sizeof(");
786 write_type(server, def->type, def, def->tname);
787 fprintf(server, ");\n");
788 }
789 }
790
791
792 static int use_return_buffer(func_t *func)
793 {
794 var_t *var;
795
796 if (!is_void(func->def->type, NULL))
797 return 1;
798
799 if (!func->args)
800 return 0;
801
802 var = func->args;
803 while (NEXT_LINK(var)) var = NEXT_LINK(var);
804 while (var)
805 {
806 if (is_attr(var->attrs, ATTR_OUT))
807 return 1;
808
809 var = PREV_LINK(var);
810 }
811
812 return 0;
813 }
814
815
816 static void write_function_stubs(type_t *iface)
817 {
818 int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
819 func_t *func = iface->funcs;
820 var_t *var;
821 var_t* explicit_handle_var;
822 unsigned int proc_offset = 0;
823 unsigned int type_offset = 2;
824 unsigned int i;
825 int in_attr;
826 int out_attr;
827
828 while (NEXT_LINK(func)) func = NEXT_LINK(func);
829 while (func)
830 {
831 var_t *def = func->def;
832
833 /* check for a defined binding handle */
834 explicit_handle_var = get_explicit_handle_var(func);
835 if (explicit_handle)
836 {
837 if (!explicit_handle_var)
838 {
839 error("%s() does not define an explicit binding handle!\n", def->name);
840 return;
841 }
842 }
843 else
844 {
845 if (explicit_handle_var)
846 {
847 error("%s() must not define a binding handle!\n", def->name);
848 return;
849 }
850 }
851
852 fprintf(server, "void __RPC_STUB\n");
853 fprintf(server, "%s_", iface->name);
854 write_name(server, def);
855 fprintf(server, "(\n");
856 indent++;
857 print_server("PRPC_MESSAGE _pRpcMessage)\n");
858 indent--;
859
860 /* write the functions body */
861 fprintf(server, "{\n");
862 indent++;
863
864 /* declare return value '_RetVal' */
865 if (!is_void(def->type, NULL))
866 {
867 print_server("");
868 write_type(server, def->type, def, def->tname);
869 fprintf(server, " _RetVal;\n");
870 }
871
872 /* declare arguments */
873 if (func->args)
874 {
875 i = 0;
876 var = func->args;
877 while (NEXT_LINK(var)) var = NEXT_LINK(var);
878 while (var)
879 {
880 in_attr = is_attr(var->attrs, ATTR_IN);
881 out_attr = is_attr(var->attrs, ATTR_OUT);
882 if (!out_attr && !in_attr)
883 in_attr = 1;
884 if (!in_attr)
885 {
886 print_server("");
887 write_type(server, var->type, NULL, var->tname);
888 fprintf(server, " _W%u;\n", i);
889 i++;
890 }
891
892 print_server("");
893 write_type(server, var->type, var, var->tname);
894 fprintf(server, " ");
895 write_name(server, var);
896 fprintf(server, ";\n");
897
898 var = PREV_LINK(var);
899 }
900 }
901
902 print_server("MIDL_STUB_MESSAGE _StubMsg;\n");
903 print_server("RPC_STATUS _Status;\n");
904 fprintf(server, "\n");
905
906
907 print_server("((void)(_Status));\n");
908 print_server("NdrServerInitializeNew(\n");
909 indent++;
910 print_server("_pRpcMessage,\n");
911 print_server("&_StubMsg,\n");
912 print_server("&%s_StubDesc);\n", iface->name);
913 indent--;
914 fprintf(server, "\n");
915
916 if (explicit_handle)
917 {
918 print_server("%s = _pRpcMessage->Handle;\n", explicit_handle_var->name);
919 fprintf(server, "\n");
920 }
921
922 init_pointers(func);
923
924 print_server("RpcTryFinally\n");
925 print_server("{\n");
926 indent++;
927 print_server("RpcTryExcept\n");
928 print_server("{\n");
929 indent++;
930
931 if (func->args)
932 {
933 print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
934 indent++;
935 print_server("NdrConvert(\n");
936 indent++;
937 print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
938 print_server("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);
939 indent -= 2;
940 fprintf(server, "\n");
941
942 unmarshall_in_arguments(func, &type_offset);
943 }
944
945 print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");
946 print_server("{\n");
947 indent++;
948 print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
949 indent--;
950 print_server("}\n");
951 indent--;
952 print_server("}\n");
953 print_server("RpcExcept(RPC_BAD_STUB_DATA_EXCEPTION_FILTER)\n");
954 print_server("{\n");
955 indent++;
956 print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
957 indent--;
958 print_server("}\n");
959 print_server("RpcEndExcept\n");
960 fprintf(server, "\n");
961
962 /* assign out arguments */
963 if (func->args)
964 {
965 i = 0;
966 var = func->args;
967 while (NEXT_LINK(var)) var = NEXT_LINK(var);
968 while (var)
969 {
970 in_attr = is_attr(var->attrs, ATTR_IN);
971 out_attr = is_attr(var->attrs, ATTR_OUT);
972 if (!out_attr && !in_attr)
973 in_attr = 1;
974 if (!in_attr)
975 {
976 print_server("");
977 write_name(server, var);
978 fprintf(server, " = &_W%u;\n", i);
979 i++;
980 }
981
982 var = PREV_LINK(var);
983 }
984
985 if (i)
986 fprintf(server, "\n");
987 }
988
989 /* Call the real server function */
990 if (!is_void(def->type, NULL))
991 print_server("_RetVal = ");
992 else
993 print_server("");
994 write_name(server, def);
995
996 if (func->args)
997 {
998 int first_arg = 1;
999
1000 fprintf(server, "(\n");
1001 indent++;
1002 var = func->args;
1003 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1004 while (var)
1005 {
1006 if (first_arg)
1007 first_arg = 0;
1008 else
1009 fprintf(server, ",\n");
1010 print_server("");
1011 write_name(server, var);
1012 var = PREV_LINK(var);
1013 }
1014 fprintf(server, ");\n");
1015 indent--;
1016 }
1017 else
1018 {
1019 fprintf(server, "();\n");
1020 }
1021
1022 /* allocate and fill the return message buffer */
1023 if (use_return_buffer(func))
1024 {
1025 print_message_buffer_size(func);
1026 print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
1027 fprintf(server, "\n");
1028 print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");
1029 print_server("if (_Status)\n");
1030 indent++;
1031 print_server("RpcRaiseException(_Status);\n");
1032 indent--;
1033 fprintf(server, "\n");
1034 print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)_pRpcMessage->Buffer;\n");
1035
1036 /* marshall the out arguments */
1037 marshall_out_arguments(func);
1038 }
1039
1040 indent--;
1041 print_server("}\n");
1042 print_server("RpcFinally\n");
1043 print_server("{\n");
1044 print_server("}\n");
1045 print_server("RpcEndFinally\n");
1046
1047 /* calculate buffer length */
1048 fprintf(server, "\n");
1049 print_server("_pRpcMessage->BufferLength =\n");
1050 indent++;
1051 print_server("(unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer);\n");
1052 indent--;
1053 indent--;
1054 fprintf(server, "}\n");
1055 fprintf(server, "\n");
1056
1057 /* update proc_offset */
1058 if (func->args)
1059 {
1060 var = func->args;
1061 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1062 while (var)
1063 {
1064 proc_offset += 2; /* FIXME */
1065 var = PREV_LINK(var);
1066 }
1067 }
1068 proc_offset += 2; /* FIXME */
1069
1070 func = PREV_LINK(func);
1071 }
1072 }
1073
1074
1075 static void write_dispatchtable(type_t *iface)
1076 {
1077 unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
1078 unsigned long method_count = 0;
1079 func_t *cur = iface->funcs;
1080
1081 print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name);
1082 print_server("{\n");
1083 indent++;
1084 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
1085 while (cur)
1086 {
1087 var_t *def = cur->def;
1088
1089 print_server("%s_", iface->name);
1090 write_name(server, def);
1091 fprintf(server, ",\n");
1092
1093 method_count++;
1094 cur = PREV_LINK(cur);
1095 }
1096 print_server("0\n");
1097 indent--;
1098 print_server("};\n");
1099 print_server("RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable =\n", iface->name, LOWORD(ver), HIWORD(ver));
1100 print_server("{\n");
1101 indent++;
1102 print_server("%u,\n", method_count);
1103 print_server("%s_table\n", iface->name);
1104 indent--;
1105 print_server("};\n");
1106 fprintf(server, "\n");
1107 }
1108
1109
1110 static void write_stubdescdecl(type_t *iface)
1111 {
1112 print_server("extern const MIDL_STUB_DESC %s_StubDesc;\n", iface->name);
1113 fprintf(server, "\n");
1114 }
1115
1116
1117 static void write_stubdescriptor(type_t *iface)
1118 {
1119 print_server("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name);
1120 print_server("{\n");
1121 indent++;
1122 print_server("(void __RPC_FAR *)& %s___RpcServerInterface,\n", iface->name);
1123 print_server("MIDL_user_allocate,\n");
1124 print_server("MIDL_user_free,\n");
1125 print_server("{NULL},\n");
1126 print_server("0,\n");
1127 print_server("0,\n");
1128 print_server("0,\n");
1129 print_server("0,\n");
1130 print_server("__MIDL_TypeFormatString.Format,\n");
1131 print_server("1, /* -error bounds_check flag */\n");
1132 print_server("0x10001, /* Ndr library version */\n");
1133 print_server("0,\n");
1134 print_server("0x50100a4, /* MIDL Version 5.1.164 */\n");
1135 print_server("0,\n");
1136 print_server("0,\n");
1137 print_server("0, /* notify & notify_flag routine table */\n");
1138 print_server("1, /* Flags */\n");
1139 print_server("0, /* Reserved3 */\n");
1140 print_server("0, /* Reserved4 */\n");
1141 print_server("0 /* Reserved5 */\n");
1142 indent--;
1143 print_server("};\n");
1144 fprintf(server, "\n");
1145 }
1146
1147
1148 static void write_serverinterfacedecl(type_t *iface)
1149 {
1150 unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
1151 UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
1152
1153 print_server("extern RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, LOWORD(ver), HIWORD(ver));
1154 fprintf(server, "\n");
1155 print_server("static const RPC_SERVER_INTERFACE %s___RpcServerInterface =\n", iface->name );
1156 print_server("{\n");
1157 indent++;
1158 print_server("sizeof(RPC_SERVER_INTERFACE),\n");
1159 print_server("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n",
1160 uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
1161 uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6],
1162 uuid->Data4[7], LOWORD(ver), HIWORD(ver));
1163 print_server("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */
1164 print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, LOWORD(ver), HIWORD(ver));
1165 print_server("0,\n");
1166 print_server("0,\n");
1167 print_server("0,\n");
1168 print_server("0,\n");
1169 print_server("0,\n");
1170 indent--;
1171 print_server("};\n");
1172 if (old_names)
1173 print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
1174 iface->name, iface->name);
1175 else
1176 print_server("RPC_IF_HANDLE %s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
1177 iface->name, LOWORD(ver), HIWORD(ver), iface->name);
1178 fprintf(server, "\n");
1179 }
1180
1181 static void write_formatdesc( const char *str )
1182 {
1183 print_server("typedef struct _MIDL_%s_FORMAT_STRING\n", str );
1184 print_server("{\n");
1185 indent++;
1186 print_server("short Pad;\n");
1187 print_server("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str);
1188 indent--;
1189 print_server("} MIDL_%s_FORMAT_STRING;\n", str);
1190 print_server("\n");
1191 }
1192
1193 static int get_type_format_string_size(type_t *iface)
1194 {
1195 int size = 3;
1196 func_t *func;
1197 var_t *var;
1198
1199 /* determine the proc format string size */
1200 func = iface->funcs;
1201 while (NEXT_LINK(func)) func = NEXT_LINK(func);
1202 while (func)
1203 {
1204 /* argument list size */
1205 if (func->args)
1206 {
1207 var = func->args;
1208 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1209 while (var)
1210 {
1211 if (var->ptr_level == 1)
1212 {
1213 if (is_base_type(var->type))
1214 size += 4;
1215 }
1216
1217 var = PREV_LINK(var);
1218 }
1219 }
1220
1221 func = PREV_LINK(func);
1222 }
1223
1224 return size;
1225 }
1226
1227
1228 static int get_proc_format_string_size(type_t *iface)
1229 {
1230 int size = 1;
1231 func_t *func;
1232 var_t *var;
1233
1234 /* determine the proc format string size */
1235 func = iface->funcs;
1236 while (NEXT_LINK(func)) func = NEXT_LINK(func);
1237 while (func)
1238 {
1239 /* argument list size */
1240 if (func->args)
1241 {
1242 var = func->args;
1243 while (NEXT_LINK(var)) var = NEXT_LINK(var);
1244 while (var)
1245 {
1246 switch (var->ptr_level)
1247 {
1248 case 0:
1249 if (is_base_type(var->type))
1250 size += 2;
1251 break;
1252
1253 case 1:
1254 if (is_base_type(var->type))
1255 size += 4;
1256 break;
1257 }
1258
1259 var = PREV_LINK(var);
1260 }
1261 }
1262
1263 /* return value size */
1264 size += 2;
1265 func = PREV_LINK(func);
1266 }
1267
1268 return size;
1269 }
1270
1271
1272 static void write_formatstringsdecl(type_t *iface)
1273 {
1274 print_server("#define TYPE_FORMAT_STRING_SIZE %d\n",
1275 get_type_format_string_size(iface));
1276
1277 print_server("#define PROC_FORMAT_STRING_SIZE %d\n",
1278 get_proc_format_string_size(iface));
1279
1280 fprintf(server, "\n");
1281 write_formatdesc("TYPE");
1282 write_formatdesc("PROC");
1283 fprintf(server, "\n");
1284 print_server("extern const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n");
1285 print_server("extern const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n");
1286 print_server("\n");
1287 }
1288
1289
1290 static void init_server(void)
1291 {
1292 if (server)
1293 return;
1294 if (!(server = fopen(server_name, "w")))
1295 error("Could not open %s for output\n", server_name);
1296
1297 print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name);
1298 print_server("#include<string.h>\n");
1299 fprintf(server, "\n");
1300 print_server("#include\"%s\"\n", header_name);
1301 fprintf(server, "\n");
1302 }
1303
1304
1305 void write_server(ifref_t *ifaces)
1306 {
1307 ifref_t *iface = ifaces;
1308
1309 if (!do_server)
1310 return;
1311 if (!iface)
1312 return;
1313 END_OF_LIST(iface);
1314
1315 init_server();
1316 if (!server)
1317 return;
1318
1319 while (iface)
1320 {
1321 fprintf(server, "/*****************************************************************************\n");
1322 fprintf(server, " * %s interface\n", iface->iface->name);
1323 fprintf(server, " */\n");
1324 fprintf(server, "\n");
1325
1326 write_formatstringsdecl(iface->iface);
1327 write_serverinterfacedecl(iface->iface);
1328 write_stubdescdecl(iface->iface);
1329
1330 write_function_stubs(iface->iface);
1331
1332 write_stubdescriptor(iface->iface);
1333 write_dispatchtable(iface->iface);
1334
1335 print_server("#if !defined(__RPC_WIN32__)\n");
1336 print_server("#error Invalid build platform for this stub.\n");
1337 print_server("#endif\n");
1338 fprintf(server, "\n");
1339
1340 write_procformatstring(iface->iface);
1341 write_typeformatstring(iface->iface);
1342
1343 fprintf(server, "\n");
1344
1345 iface = PREV_LINK(iface);
1346 }
1347
1348 fclose(server);
1349 }