4 * Copyright 2005 Eric Kohl
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.
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.
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
34 #define END_OF_LIST(list) \
37 while (NEXT_LINK(list)) \
38 list = NEXT_LINK(list); \
43 static int indent
= 0;
45 static int print_client( const char *format
, ... )
51 for (i
= 0; i
< indent
; i
++)
53 r
= vfprintf(client
, format
, va
);
60 get_var_stack_offset_32(func_t
*func
, char *name
)
62 unsigned int offset
= 0;
66 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
69 if (!strcmp(var
->name
, name
))
72 if (var
->type
->type
== RPC_FC_DOUBLE
||
73 var
->type
->type
== RPC_FC_HYPER
)
86 get_var_stack_offset_64(func_t
*func
, char *name
)
88 unsigned int offset
= 0;
92 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
95 if (!strcmp(var
->name
, name
))
100 var
= PREV_LINK(var
);
108 get_var_type_offset(var_t
*var
)
110 unsigned int toffset
= 0;
114 if (var
->ptr_level
== 0)
116 if ((var
->type
->type
== RPC_FC_RP
) &&
117 (var
->type
->ref
->ref
->type
== RPC_FC_STRUCT
))
119 var_t
*field
= var
->type
->ref
->ref
->fields
;
122 while (NEXT_LINK(field
)) field
= NEXT_LINK(field
);
126 field
= PREV_LINK(field
);
134 else if (var
->ptr_level
== 1)
136 sizeis_attr
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
137 string_attr
= is_attr(var
->attrs
, ATTR_STRING
);
143 if (var
->type
->type
== RPC_FC_BYTE
||
144 var
->type
->type
== RPC_FC_CHAR
||
145 var
->type
->type
== RPC_FC_WCHAR
)
150 if (is_base_type(var
->type
))
156 if (is_base_type(var
->type
))
165 static type_t
*get_type_by_name(func_t
*func
, char *name
)
170 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
173 if (!strcmp(var
->name
, name
))
176 var
= PREV_LINK(var
);
184 get_base_type(unsigned char type
)
202 static int get_type_size(type_t
*type
, int alignment
)
213 size
= ((size
+ alignment
- 1) & ~(alignment
-1));
220 size
= ((size
+ alignment
- 1) & ~(alignment
-1));
227 size
= ((size
+ alignment
- 1) & ~(alignment
-1));
233 size
= ((size
+ alignment
- 1) & ~(alignment
-1));
241 field
= type
->fields
;
243 while (NEXT_LINK(field
)) field
= NEXT_LINK(field
);
246 size
+= get_type_size(field
->type
, alignment
);
247 field
= PREV_LINK(field
);
252 error("%s:%d Unknown/unsupported type 0x%x\n",
253 __FUNCTION__
,__LINE__
, type
->type
);
261 static int get_type_alignment(type_t
*type
)
291 error("%s:%d Unknown/unsupported type 0x%x\n",
292 __FUNCTION__
,__LINE__
, type
->type
);
300 static void write_procformatstring(type_t
*iface
)
302 func_t
*func
= iface
->funcs
;
304 unsigned int type_offset
= 2;
305 int in_attr
, out_attr
;
307 print_client("const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
310 print_client("0,\n");
314 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
317 /* emit argument data */
321 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
324 out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
325 in_attr
= is_attr(var
->attrs
, ATTR_IN
);
327 /* set 'in' attribute if neither 'in' nor 'out' is set */
328 if (!out_attr
&& !in_attr
)
331 if (var
->ptr_level
== 0)
333 if (is_base_type(var
->type
))
335 print_client("0x4e, /* FC_IN_PARAM_BASETYPE */\n");
336 print_client("0x%02x, /* FC_<type> */\n",
337 get_base_type(var
->type
->type
));
339 else if (var
->type
->type
== RPC_FC_RP
)
341 if (in_attr
& !out_attr
)
342 print_client("0x4d, /* FC_IN_PARAM */\n");
343 else if (!in_attr
& out_attr
)
344 print_client("0x51, /* FC_OUT_PARAM */\n");
345 else if (in_attr
& out_attr
)
346 print_client("0x50, /* FC_IN_OUT_PARAM */\n");
347 fprintf(client
, "#ifndef _ALPHA_\n");
348 print_client("0x01,\n");
349 fprintf(client
, "#else\n");
350 print_client("0x02,\n");
351 fprintf(client
, "#endif\n");
352 print_client("NdrFcShort(0x%x),\n", type_offset
);
356 print_client("0x4d, /* FC_IN_PARAM */\n");
358 error("%s:%d Unknown/unsupported type 0x%x\n",
359 __FUNCTION__
,__LINE__
, var
->type
->type
);
363 else if (var
->ptr_level
== 1)
365 if (in_attr
& !out_attr
)
366 print_client("0x4d, /* FC_IN_PARAM */\n");
367 else if (!in_attr
& out_attr
)
368 print_client("0x51, /* FC_OUT_PARAM */\n");
369 else if (in_attr
& out_attr
)
370 print_client("0x50, /* FC_IN_OUT_PARAM */\n");
371 fprintf(client
, "#ifndef _ALPHA_\n");
372 print_client("0x01,\n");
373 fprintf(client
, "#else\n");
374 print_client("0x02,\n");
375 fprintf(client
, "#endif\n");
376 print_client("NdrFcShort(0x%x),\n", type_offset
);
380 error("%s:%d Pointer level %d is not supported!\n",
381 __FUNCTION__
,__LINE__
, var
->ptr_level
);
385 type_offset
+= get_var_type_offset(var
);
387 var
= PREV_LINK(var
);
391 /* emit return value data */
393 if (is_void(var
->type
, NULL
))
395 print_client("0x5b, /* FC_END */\n");
396 print_client("0x5c, /* FC_PAD */\n");
398 else if (is_base_type(var
->type
))
400 print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
401 print_client("0x%02x, /* FC_<type> */\n", get_base_type(var
->type
->type
));
405 error("%s:%d Unknown/unsupported type 0x%x\n",
406 __FUNCTION__
,__LINE__
, var
->type
->type
);
410 func
= PREV_LINK(func
);
413 print_client("0x0\n");
417 print_client("};\n");
422 static void write_typeformatstring(type_t
*iface
)
424 func_t
*func
= iface
->funcs
;
427 int in_attr
, out_attr
;
429 int ptr_attr
, ref_attr
, unique_attr
;
432 print_client("const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");
435 print_client("0,\n");
438 print_client("NdrFcShort(0x00),\n");
440 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
446 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
449 in_attr
= is_attr(var
->attrs
, ATTR_IN
);
450 out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
451 string_attr
= is_attr(var
->attrs
, ATTR_STRING
);
453 if (var
->ptr_level
> 1)
455 error("Function '%s' argument '%s': Pointer level %d not supported!\n",
456 func
->def
->name
, var
->name
, var
->ptr_level
);
460 if (var
->ptr_level
== 0)
462 if (!is_base_type(var
->type
))
464 if (var
->type
->type
== RPC_FC_RP
)
468 unsigned char flags
= 0;
470 if (!in_attr
&& out_attr
)
471 flags
|= RPC_FC_P_ONSTACK
;
473 print_client("0x11, 0x%02X, /* FC_RP, [flags] */\n", flags
);
474 print_client("NdrFcShort(0x%02X),\n", 0x02);
475 print_client("0x%02X,\n", var
->type
->ref
->ref
->type
);
476 print_client("0x%02X,\n", 3); /* alignment - 1 */
477 print_client("NdrFcShort(0x%02X),\n", get_type_size(var
->type
->ref
->ref
, 4));
479 field
= var
->type
->ref
->ref
->fields
;
480 while (NEXT_LINK(field
)) field
= NEXT_LINK(field
);
483 print_client("0x%02X,\n", get_base_type(field
->type
->type
));
485 field
= PREV_LINK(field
);
489 print_client("0x5c, /* FC_PAD */\n");
492 print_client("0x5b, /* FC_END */\n");
497 error("%s:%d Unknown/unsupported type 0x%x\n",
498 __FUNCTION__
,__LINE__
, var
->type
->type
);
503 else if (var
->ptr_level
== 1)
505 ptr_attr
= is_attr(var
->attrs
, ATTR_PTR
);
506 ref_attr
= is_attr(var
->attrs
, ATTR_REF
);
507 unique_attr
= is_attr(var
->attrs
, ATTR_UNIQUE
);
508 sizeis_attr
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
510 if (ptr_attr
+ ref_attr
+ unique_attr
== 0)
515 unsigned char type_type
= 0;
517 type
= get_type_by_name(func
, ((var_t
*)sizeis_attr
)->name
);
519 type_type
= type
->type
;
522 print_client("0x11, 0x00, /* FC_RP */\n");
523 else if (unique_attr
)
524 print_client("0x12, 0x00, /* FC_UP */\n");
526 print_client("0x14, 0x00, /* FC_FP */\n");
528 print_client("NdrFcShort(0x02),\n");
532 if (var
->type
->type
== RPC_FC_WCHAR
)
533 print_client("0x25, /* FC_C_WSTRING */\n");
535 print_client("0x22, /* FC_C_CSTRING */\n");
536 print_client("0x44, /* FC_STRING_SIZED */\n");
537 print_client("0x%02x,\n", 0x20 + type_type
);
538 print_client("0x00,\n");
540 fprintf(client
, "#ifndef _ALPHA_\n");
541 print_client("NdrFcShort(0x%02X),\n",
542 get_var_stack_offset_32(func
, ((var_t
*)sizeis_attr
)->name
));
543 fprintf(client
, "#else\n");
544 print_client("NdrFcShort(0x%02X),\n",
545 get_var_stack_offset_64(func
, ((var_t
*)sizeis_attr
)->name
));
546 fprintf(client
, "#endif\n");
550 print_client("0x1b, /* FC_CARRAY */\n");
551 print_client("0x%02x,\n", get_type_alignment(var
->type
) - 1);
552 print_client("NdrFcShort(0x%02x),\n", get_type_size(var
->type
, 1));
553 print_client("0x%02x,\n", 0x20 + type_type
);
555 print_client("0x54, /* FC_DEREFERENCE */\n");
557 print_client("0x00, /* */\n");
559 fprintf(client
, "#ifndef _ALPHA_\n");
560 print_client("NdrFcShort(0x%02X),\n",
561 get_var_stack_offset_32(func
, ((var_t
*)sizeis_attr
)->name
));
562 fprintf(client
, "#else\n");
563 print_client("NdrFcShort(0x%02X),\n",
564 get_var_stack_offset_64(func
, ((var_t
*)sizeis_attr
)->name
));
565 fprintf(client
, "#endif\n");
566 print_client("0x%02x,\n", get_base_type(var
->type
->type
));
567 print_client("0x5b, /* FC_END */\n");
570 else if (is_base_type(var
->type
))
572 if (out_attr
&& !in_attr
)
575 print_client("0x11, 0x0c, /* FC_RP [allocated_on_stack] [simple_pointer] */\n");
576 else if (unique_attr
)
577 print_client("0x12, 0x0c, /* FC_UP [allocated_on_stack] [simple_pointer] */\n");
579 print_client("0x14, 0x0c, /* FC_FP [allocated_on_stack] [simple_pointer] */\n");
584 print_client("0x11, 0x08, /* FC_RP [simple_pointer] */\n");
585 else if (unique_attr
)
586 print_client("0x12, 0x08, /* FC_UP [simple_pointer] */\n");
588 print_client("0x14, 0x08, /* FC_FP [simple_pointer] */\n");
593 if (var
->type
->type
== RPC_FC_CHAR
)
594 print_client("0x%02x, /* FC_C_CSTRING */\n", RPC_FC_C_CSTRING
);
595 else if (var
->type
->type
== RPC_FC_WCHAR
)
596 print_client("0x%02x, /* FC_C_WSTRING */\n", RPC_FC_C_WSTRING
);
599 error("%s: Invalid type!\n", __FUNCTION__
);
604 print_client("0x%02x, /* FC_<type> */\n", get_base_type(var
->type
->type
));
605 print_client("0x5c, /* FC_PAD */\n");
609 var
= PREV_LINK(var
);
613 func
= PREV_LINK(func
);
616 print_client("0x0\n");
620 print_client("};\n");
625 static void print_message_buffer_size(func_t
*func
, unsigned int *type_offset
)
627 unsigned int local_type_offset
= *type_offset
;
628 unsigned int alignment
= 0;
634 int nothing_printed
= 1;
635 int ptr_attr
, ref_attr
, unique_attr
;
636 int padding
= 0, first_padding
= 0;
640 print_client("_StubMsg.BufferLength =");
644 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
645 for (; var
; var
= PREV_LINK(var
))
647 out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
648 in_attr
= is_attr(var
->attrs
, ATTR_IN
);
650 /* set 'in' attribute if neither 'in' nor 'out' is found */
651 if (!out_attr
&& !in_attr
)
654 ptr_attr
= is_attr(var
->attrs
, ATTR_PTR
);
655 ref_attr
= is_attr(var
->attrs
, ATTR_REF
);
656 unique_attr
= is_attr(var
->attrs
, ATTR_UNIQUE
);
658 /* default to 'ref' attribute */
659 if (ptr_attr
+ ref_attr
+ unique_attr
== 0)
665 string_attr
= is_attr(var
->attrs
, ATTR_STRING
);
666 sizeis_attr
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
668 if (var
->ptr_level
== 1)
670 if (string_attr
&& !sizeis_attr
)
672 /* non-sized conformant string */
673 if (var
->type
->type
== RPC_FC_CHAR
|| var
->type
->type
== RPC_FC_WCHAR
)
675 size
= (unique_attr
) ? 16 : 12;
679 else if (sizeis_attr
&& !string_attr
)
681 /* conformant arrays */
687 else if (!sizeis_attr
&& !string_attr
)
689 /* simple pointers */
690 if (is_base_type(var
->type
))
693 switch (var
->type
->type
)
706 if (last_size
> 0 && last_size
< 2)
707 alignment
+= (2 - last_size
);
714 if (last_size
> 0 && last_size
< 4)
715 alignment
+= (4 - last_size
);
721 if (last_size
> 0 && last_size
< 4)
722 alignment
+= (4 - last_size
);
730 error("%s:%d Unknown/unsupported type 0x%x\n",
731 __FUNCTION__
,__LINE__
, var
->type
->type
);
740 /* simple pointer to a struct */
749 switch (var
->type
->type
)
762 if (last_size
> 0 && last_size
< 2)
763 alignment
+= (2 - last_size
);
770 if (last_size
> 0 && last_size
< 4)
771 alignment
+= (4 - last_size
);
777 if (last_size
> 0 && last_size
< 4)
778 alignment
+= (4 - last_size
);
792 error("%s:%d Unknown/unsupported type 0x%x\n",
793 __FUNCTION__
,__LINE__
, var
->type
->type
);
799 fprintf(client
, " +");
800 fprintf(client
, " %dU", (size
== 0) ? 0 : size
+ alignment
+ first_padding
+ padding
);
802 if (first_padding
!= 0)
806 if (var
->ptr_level
== 1)
808 if (string_attr
&& !sizeis_attr
)
810 /* non-sized conformant string */
811 if (var
->type
->type
== RPC_FC_CHAR
|| var
->type
->type
== RPC_FC_WCHAR
)
817 else if (sizeis_attr
&& !string_attr
)
819 /* conformant arrays */
831 fprintf(client
, " 0U");
833 fprintf(client
, ";\n");
835 /* get string size */
840 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
841 for (; var
; var
= PREV_LINK(var
))
843 out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
844 in_attr
= is_attr(var
->attrs
, ATTR_IN
);
846 /* default to 'in' attribute */
847 if (!out_attr
&& !in_attr
)
850 ptr_attr
= is_attr(var
->attrs
, ATTR_PTR
);
851 ref_attr
= is_attr(var
->attrs
, ATTR_REF
);
852 unique_attr
= is_attr(var
->attrs
, ATTR_UNIQUE
);
854 /* default to 'ref' attribute */
855 if (ptr_attr
+ ref_attr
+ unique_attr
== 0)
858 string_attr
= is_attr(var
->attrs
, ATTR_STRING
);
859 sizeis_attr
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
863 if (var
->ptr_level
== 0)
865 if (var
->type
->type
== RPC_FC_RP
&&
866 var
->type
->ref
->ref
->type
== RPC_FC_STRUCT
)
868 print_client("NdrSimpleStructBufferSize(\n");
870 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
871 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
872 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
873 local_type_offset
+ 4);
878 else if (var
->ptr_level
== 1)
882 if ((var
->type
->type
== RPC_FC_CHAR
||
883 var
->type
->type
== RPC_FC_WCHAR
))
887 print_client("NdrConformantStringBufferSize(\n");
889 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
890 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
891 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
892 local_type_offset
+ 2);
896 else if (unique_attr
)
898 print_client("NdrPointerBufferSize(\n");
900 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
901 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
902 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
909 /* FIXME: not supported yet */
917 fprintf(client
, "\n");
918 print_client("_StubMsg.MaxCount = %s;\n",
919 ((var_t
*)sizeis_attr
)->name
);
920 fprintf(client
, "\n");
924 print_client("NdrConformantArrayBufferSize(\n");
926 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
927 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
928 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
929 local_type_offset
+ 4);
933 else if (unique_attr
)
935 print_client("NdrPointerBufferSize(\n");
937 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
938 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
939 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
946 /* FIXME: not supported yet */
953 /* calculate the next type offset */
954 local_type_offset
+= get_var_type_offset(var
);
958 fprintf(client
, "\n");
963 static void marshall_in_arguments(func_t
*func
, unsigned int *type_offset
)
965 unsigned int local_type_offset
= *type_offset
;
966 unsigned int alignment
;
968 unsigned int last_size
= 0;
972 int ptr_attr
, ref_attr
, unique_attr
;
975 int default_align
= 0;
981 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
982 for (; var
; var
= PREV_LINK(var
))
984 out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
985 in_attr
= is_attr(var
->attrs
, ATTR_IN
);
987 /* set 'in' attribute if neither 'in' nor 'out' is set */
988 if (!out_attr
&& !in_attr
)
993 if (var
->ptr_level
> 1)
995 error("Function '%s' argument '%s': Pointer level %d not supported!\n",
996 func
->def
->name
, var
->name
, var
->ptr_level
);
1000 if (var
->ptr_level
== 1)
1002 ptr_attr
= is_attr(var
->attrs
, ATTR_PTR
);
1003 ref_attr
= is_attr(var
->attrs
, ATTR_REF
);
1004 unique_attr
= is_attr(var
->attrs
, ATTR_UNIQUE
);
1005 if (ptr_attr
+ ref_attr
+ unique_attr
== 0)
1008 string_attr
= is_attr(var
->attrs
, ATTR_STRING
);
1009 sizeis_attr
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
1015 print_client("_StubMsg.MaxCount = %s;\n",
1016 ((var_t
*)sizeis_attr
)->name
);
1017 fprintf(client
, "\n");
1019 print_client("NdrConformantArrayMarshall(\n");
1021 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1022 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
1023 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
1024 local_type_offset
+ 4);
1026 fprintf(client
, "\n");
1031 (var
->type
->type
== RPC_FC_CHAR
|| var
->type
->type
== RPC_FC_WCHAR
))
1033 print_client("NdrConformantStringMarshall(\n");
1035 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1036 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
1037 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
1038 local_type_offset
+ 2);
1040 fprintf(client
, "\n");
1046 switch (var
->type
->type
)
1059 if (last_size
> 0 && last_size
< 2)
1060 alignment
= (2 - last_size
);
1067 if (last_size
> 0 && last_size
< 4)
1068 alignment
= (4 - last_size
);
1074 if (last_size
> 0 && last_size
< 4)
1075 alignment
= (4 - last_size
);
1083 error("%s:%d Unknown/unsupported type 0x%x\n",
1084 __FUNCTION__
,__LINE__
, var
->type
->type
);
1092 print_client("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");
1093 fprintf(client
, "\n");
1098 print_client("_StubMsg.Buffer += %u;\n", alignment
);
1100 print_client("*((");
1101 write_type(client
, var
->type
, NULL
, var
->tname
);
1102 fprintf(client
, " __RPC_FAR*)_StubMsg.Buffer) = ");
1103 if (var
->ptr_level
== 1)
1104 fprintf(client
, "*");
1105 write_name(client
, var
);
1106 fprintf(client
, ";\n");
1107 print_client("_StubMsg.Buffer += sizeof(");
1108 write_type(client
, var
->type
, NULL
, var
->tname
);
1109 fprintf(client
, ");\n");
1110 fprintf(client
, "\n");
1116 else if (unique_attr
)
1120 print_client("_StubMsg.MaxCount = %s;\n",
1121 ((var_t
*)sizeis_attr
)->name
);
1122 fprintf(client
, "\n");
1125 print_client("NdrPointerMarshall(\n");
1127 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1128 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
1129 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
1132 fprintf(client
, "\n");
1138 if (is_base_type(var
->type
))
1141 switch (var
->type
->type
)
1154 if (last_size
> 0 && last_size
< 2)
1155 alignment
= (2 - last_size
);
1162 if (last_size
> 0 && last_size
< 4)
1163 alignment
= (4 - last_size
);
1169 if (last_size
> 0 && last_size
< 4)
1170 alignment
= (4 - last_size
);
1178 error("%s:%d Unknown/unsupported type 0x%x\n",
1179 __FUNCTION__
,__LINE__
, var
->type
->type
);
1187 fprintf(client
, "\n");
1188 print_client("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");
1189 fprintf(client
, "\n");
1194 print_client("_StubMsg.Buffer += %u;\n", alignment
);
1196 print_client("*((");
1197 write_type(client
, var
->type
, NULL
, var
->tname
);
1198 fprintf(client
, " __RPC_FAR*)_StubMsg.Buffer) = ");
1199 if (var
->ptr_level
== 1)
1200 fprintf(client
, "*");
1201 write_name(client
, var
);
1202 fprintf(client
, ";\n");
1203 print_client("_StubMsg.Buffer += sizeof(");
1204 write_type(client
, var
->type
, NULL
, var
->tname
);
1205 fprintf(client
, ");\n");
1206 fprintf(client
, "\n");
1211 else if (var
->type
->type
== RPC_FC_RP
)
1213 if (var
->type
->ref
->ref
->type
== RPC_FC_STRUCT
)
1215 print_client("NdrSimpleStructMarshall(\n");
1217 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1218 print_client("(unsigned char __RPC_FAR *)%s,\n", var
->name
);
1219 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",
1220 local_type_offset
+ 4);
1222 fprintf(client
, "\n");
1229 /* calculate the next type offset */
1230 local_type_offset
+= get_var_type_offset(var
);
1235 static void unmarshall_out_arguments(func_t
*func
, unsigned int *type_offset
)
1237 unsigned int alignment
;
1239 unsigned int last_size
= 0;
1242 int ptr_attr
, ref_attr
, unique_attr
;
1246 unsigned int local_type_offset
= *type_offset
;
1247 int default_align
= 0;
1251 /* unmarshall the out arguments */
1255 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
1256 for (; var
; var
= PREV_LINK(var
))
1258 out_attr
= is_attr(var
->attrs
, ATTR_OUT
);
1259 sizeis_attr
= get_attrp(var
->attrs
, ATTR_SIZEIS
);
1260 string_attr
= is_attr(var
->attrs
, ATTR_STRING
);
1262 ptr_attr
= is_attr(var
->attrs
, ATTR_PTR
);
1263 ref_attr
= is_attr(var
->attrs
, ATTR_REF
);
1264 unique_attr
= is_attr(var
->attrs
, ATTR_UNIQUE
);
1265 if (ptr_attr
+ ref_attr
+ unique_attr
== 0)
1270 if (var
->ptr_level
> 1)
1272 error("Function '%s' argument '%s': Pointer level %d not supported!\n",
1273 func
->def
->name
, var
->name
, var
->ptr_level
);
1277 if (sizeis_attr
!= NULL
)
1281 fprintf(client
, "\n");
1282 print_client("NdrConformantStringUnmarshall(\n");
1284 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1285 print_client("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var
->name
);
1286 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",
1287 local_type_offset
+ 4);
1288 print_client("(unsigned char)0);\n");
1290 fprintf(client
, "\n");
1295 fprintf(client
, "\n");
1296 print_client("NdrConformantArrayUnmarshall(\n");
1298 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1299 print_client("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var
->name
);
1300 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",
1301 local_type_offset
+ 4);
1302 print_client("(unsigned char)0);\n");
1304 fprintf(client
, "\n");
1308 else if (is_base_type(var
->type
))
1311 switch (var
->type
->type
)
1324 if (last_size
> 0 && last_size
< 2)
1325 alignment
= (2 - last_size
);
1332 if (last_size
> 0 && last_size
< 4)
1333 alignment
= (4 - last_size
);
1339 if (last_size
> 0 && last_size
< 4)
1340 alignment
= (4 - last_size
);
1348 error("%s:%d Unknown/unsupported type 0x%x\n",
1349 __FUNCTION__
,__LINE__
, var
->type
->type
);
1355 if (var
->ptr_level
== 1)
1359 fprintf(client
, "\n");
1360 print_client("NdrPointerUnmarshall(\n");
1362 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1363 print_client("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var
->name
);
1364 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",
1366 print_client("(unsigned char)0);\n");
1368 fprintf(client
, "\n");
1373 fprintf(client
, "\n");
1376 print_client("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");
1377 fprintf(client
, "\n");
1382 print_client("_StubMsg.Buffer += %u;\n", alignment
);
1386 write_name(client
, var
);
1387 fprintf(client
, " = *((");
1388 write_type(client
, var
->type
, NULL
, var
->tname
);
1389 fprintf(client
, " __RPC_FAR *)_StubMsg.Buffer);\n");
1391 print_client("_StubMsg.Buffer += sizeof(");
1392 write_type(client
, var
->type
, NULL
, var
->tname
);
1393 fprintf(client
, ");\n");
1400 else if (var
->type
->type
== RPC_FC_RP
)
1402 if (var
->type
->ref
->ref
->type
== RPC_FC_STRUCT
)
1404 fprintf(client
, "\n");
1405 print_client("NdrSimpleStructUnmarshall(\n");
1407 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1408 print_client("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var
->name
);
1409 print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",
1410 local_type_offset
+ 4);
1411 print_client("(unsigned char)0);\n");
1413 fprintf(client
, "\n");
1419 error("%s:%d Unknown/unsupported type 0x%x\n",
1420 __FUNCTION__
,__LINE__
, var
->type
->type
);
1425 /* calculate the next type offset */
1426 local_type_offset
+= get_var_type_offset(var
);
1430 /* unmarshall return value */
1431 if (!is_void(def
->type
, NULL
))
1434 switch (def
->type
->type
)
1446 if (last_size
> 0 && last_size
< 4)
1447 alignment
= (4 - last_size
);
1453 if (last_size
> 0 && last_size
< 4)
1454 alignment
= (4 - last_size
);
1458 error("%s:%d Unknown/unsupported type 0x%x\n",
1459 __FUNCTION__
,__LINE__
, def
->type
->type
);
1463 fprintf(client
, "\n");
1466 print_client("_StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~0x3);\n");
1467 fprintf(client
, "\n");
1472 print_client("_StubMsg.Buffer += %u;\n", alignment
);
1473 print_client("_RetVal = *((");
1474 write_type(client
, def
->type
, def
, def
->tname
);
1475 fprintf(client
, " __RPC_FAR *)_StubMsg.Buffer);\n");
1477 print_client("_StubMsg.Buffer += sizeof(");
1478 write_type(client
, def
->type
, def
, def
->tname
);
1479 fprintf(client
, ");\n");
1484 static void check_pointers(func_t
*func
)
1495 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
1498 ptr_attr
= is_attr(var
->attrs
, ATTR_PTR
);
1499 ref_attr
= is_attr(var
->attrs
, ATTR_REF
);
1500 unique_attr
= is_attr(var
->attrs
, ATTR_UNIQUE
);
1502 if (var
->ptr_level
== 0)
1504 if (ptr_attr
+ ref_attr
+ unique_attr
!= 0)
1506 error("The attributes [ptr], [ref] and [unique] can only be used for pointers!\n");
1512 /* default to 'ref' attribute */
1513 if (ptr_attr
+ ref_attr
+ unique_attr
== 0)
1518 if (ptr_attr
+ ref_attr
+ unique_attr
> 1)
1520 error("The attributes [ptr], [ref] and [unique] are mutually exclusive!\n");
1524 if (var
->ptr_level
== 1)
1528 print_client("if (!%s)\n", var
->name
);
1529 print_client("{\n");
1531 print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");
1533 print_client("}\n");
1534 fprintf(client
, "\n");
1537 else if (var
->ptr_level
> 1)
1539 error("Pointer level %d not supported!\n", var
->ptr_level
);
1544 var
= PREV_LINK(var
);
1549 static int use_return_buffer(func_t
*func
)
1553 if (!is_void(func
->def
->type
, NULL
))
1560 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
1563 if (is_attr(var
->attrs
, ATTR_OUT
))
1566 var
= PREV_LINK(var
);
1573 static void write_function_stubs(type_t
*iface
)
1575 char *implicit_handle
= get_attrp(iface
->attrs
, ATTR_IMPLICIT_HANDLE
);
1576 int explicit_handle
= is_attr(iface
->attrs
, ATTR_EXPLICIT_HANDLE
);
1577 func_t
*func
= iface
->funcs
;
1579 var_t
* explicit_handle_var
;
1580 int method_count
= 0;
1581 unsigned int proc_offset
= 0;
1582 unsigned int type_offset
= 2;
1584 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
1587 var_t
*def
= func
->def
;
1589 /* check for a defined binding handle */
1590 explicit_handle_var
= get_explicit_handle_var(func
);
1591 if (explicit_handle
)
1593 if (!explicit_handle_var
)
1595 error("%s() does not define an explicit binding handle!\n", def
->name
);
1601 if (explicit_handle_var
)
1603 error("%s() must not define a binding handle!\n", def
->name
);
1608 write_type(client
, def
->type
, def
, def
->tname
);
1609 fprintf(client
, " ");
1610 write_name(client
, def
);
1611 fprintf(client
, "(\n");
1613 write_args(client
, func
->args
, iface
->name
, 0, TRUE
);
1614 fprintf(client
, ")\n");
1617 /* write the functions body */
1618 fprintf(client
, "{\n");
1621 /* declare return value '_RetVal' */
1622 if (!is_void(def
->type
, NULL
))
1625 write_type(client
, def
->type
, def
, def
->tname
);
1626 fprintf(client
, " _RetVal;\n");
1629 if (implicit_handle
|| explicit_handle
)
1630 print_client("RPC_BINDING_HANDLE _Handle = 0;\n");
1631 print_client("RPC_MESSAGE _RpcMessage;\n");
1632 print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
1633 fprintf(client
, "\n");
1635 /* check pointers */
1636 check_pointers(func
);
1638 print_client("RpcTryFinally\n");
1639 print_client("{\n");
1642 print_client("NdrClientInitializeNew(\n");
1644 print_client("(PRPC_MESSAGE)&_RpcMessage,\n");
1645 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1646 print_client("(PMIDL_STUB_DESC)&%s_StubDesc,\n", iface
->name
);
1647 print_client("%d);\n", method_count
);
1649 fprintf(client
, "\n");
1651 if (implicit_handle
)
1653 print_client("_Handle = %s;\n", implicit_handle
);
1654 fprintf(client
, "\n");
1656 else if (explicit_handle
)
1658 print_client("_Handle = %s;\n", explicit_handle_var
->name
);
1659 fprintf(client
, "\n");
1662 /* emit the message buffer size */
1663 print_message_buffer_size(func
, &type_offset
);
1665 print_client("NdrGetBuffer(\n");
1667 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1668 print_client("_StubMsg.BufferLength,\n");
1669 if (implicit_handle
|| explicit_handle
)
1670 print_client("_Handle);\n");
1672 print_client("%s__MIDL_AutoBindHandle);\n", iface
->name
);
1674 fprintf(client
, "\n");
1676 /* marshal in arguments */
1677 marshall_in_arguments(func
, &type_offset
);
1679 /* send/recieve message */
1680 print_client("NdrSendReceive(\n");
1682 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1683 print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n");
1686 if (use_return_buffer(func
))
1688 /* convert data representation */
1689 fprintf(client
, "\n");
1690 print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
1692 print_client("NdrConvert(\n");
1694 print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
1695 print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset
);
1698 /* unmarshal out arguments */
1699 unmarshall_out_arguments(func
, &type_offset
);
1702 /* update type_offset */
1706 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
1709 type_offset
+= get_var_type_offset(var
);
1711 var
= PREV_LINK(var
);
1715 /* update proc_offset */
1719 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
1722 switch (var
->ptr_level
)
1725 if (is_base_type(var
->type
))
1730 if (is_base_type(var
->type
))
1735 var
= PREV_LINK(var
);
1738 proc_offset
+= 2; /* FIXME */
1741 print_client("}\n");
1742 print_client("RpcFinally\n");
1743 print_client("{\n");
1747 /* FIXME: emit client finally code */
1749 print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n");
1752 print_client("}\n");
1753 print_client("RpcEndFinally\n");
1756 /* emit return code */
1757 if (!is_void(def
->type
, NULL
))
1759 fprintf(client
, "\n");
1760 print_client("return _RetVal;\n");
1764 fprintf(client
, "}\n");
1765 fprintf(client
, "\n");
1768 func
= PREV_LINK(func
);
1773 static void write_bindinghandledecl(type_t
*iface
)
1775 if (!get_attrp(iface
->attrs
, ATTR_IMPLICIT_HANDLE
))
1777 print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n", iface
->name
);
1778 fprintf(client
, "\n");
1783 static void write_stubdescdecl(type_t
*iface
)
1785 print_client("extern const MIDL_STUB_DESC %s_StubDesc;\n", iface
->name
);
1786 fprintf(client
, "\n");
1790 static void write_stubdescriptor(type_t
*iface
)
1792 char *implicit_handle
= get_attrp(iface
->attrs
, ATTR_IMPLICIT_HANDLE
);
1794 print_client("const MIDL_STUB_DESC %s_StubDesc =\n", iface
->name
);
1795 print_client("{\n");
1797 print_client("(void __RPC_FAR *)& %s___RpcClientInterface,\n", iface
->name
);
1798 print_client("MIDL_user_allocate,\n");
1799 print_client("MIDL_user_free,\n");
1800 if (implicit_handle
)
1801 print_client("{&%s},\n", implicit_handle
);
1803 print_client("{&%s__MIDL_AutoBindHandle},\n", iface
->name
);
1804 print_client("0,\n");
1805 print_client("0,\n");
1806 print_client("0,\n");
1807 print_client("0,\n");
1808 print_client("__MIDL_TypeFormatString.Format,\n");
1809 print_client("1, /* -error bounds_check flag */\n");
1810 print_client("0x10001, /* Ndr library version */\n");
1811 print_client("0,\n");
1812 print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
1813 print_client("0,\n");
1814 print_client("0,\n");
1815 print_client("0, /* notify & notify_flag routine table */\n");
1816 print_client("1, /* Flags */\n");
1817 print_client("0, /* Reserved3 */\n");
1818 print_client("0, /* Reserved4 */\n");
1819 print_client("0 /* Reserved5 */\n");
1821 print_client("};\n");
1822 fprintf(client
, "\n");
1826 static void write_clientinterfacedecl(type_t
*iface
)
1828 unsigned long ver
= get_attrv(iface
->attrs
, ATTR_VERSION
);
1829 UUID
*uuid
= get_attrp(iface
->attrs
, ATTR_UUID
);
1831 print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface
->name
);
1832 print_client("{\n");
1834 print_client("sizeof(RPC_CLIENT_INTERFACE),\n");
1835 print_client("{{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",
1836 uuid
->Data1
, uuid
->Data2
, uuid
->Data3
, uuid
->Data4
[0], uuid
->Data4
[1],
1837 uuid
->Data4
[2], uuid
->Data4
[3], uuid
->Data4
[4], uuid
->Data4
[5], uuid
->Data4
[6],
1838 uuid
->Data4
[7], LOWORD(ver
), HIWORD(ver
));
1839 print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */
1840 print_client("0,\n");
1841 print_client("0,\n");
1842 print_client("0,\n");
1843 print_client("0,\n");
1844 print_client("0,\n");
1845 print_client("0,\n");
1847 print_client("};\n");
1849 print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
1850 iface
->name
, iface
->name
);
1852 print_client("RPC_IF_HANDLE %s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
1853 iface
->name
, LOWORD(ver
), HIWORD(ver
), iface
->name
);
1854 fprintf(client
, "\n");
1858 static void write_formatdesc( const char *str
)
1860 print_client("typedef struct _MIDL_%s_FORMAT_STRING\n", str
);
1861 print_client("{\n");
1863 print_client("short Pad;\n");
1864 print_client("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str
);
1866 print_client("} MIDL_%s_FORMAT_STRING;\n", str
);
1871 static int get_type_format_string_size(type_t
*iface
)
1877 /* determine the type format string size */
1878 func
= iface
->funcs
;
1879 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
1882 /* argument list size */
1886 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
1889 size
+= get_var_type_offset(var
);
1890 var
= PREV_LINK(var
);
1894 func
= PREV_LINK(func
);
1901 static int get_proc_format_string_size(type_t
*iface
)
1907 /* determine the proc format string size */
1908 func
= iface
->funcs
;
1909 while (NEXT_LINK(func
)) func
= NEXT_LINK(func
);
1912 /* argument list size */
1916 while (NEXT_LINK(var
)) var
= NEXT_LINK(var
);
1919 switch (var
->ptr_level
)
1922 if (is_base_type(var
->type
))
1924 else if (var
->type
->type
== RPC_FC_RP
)
1929 if (is_base_type(var
->type
))
1934 var
= PREV_LINK(var
);
1938 /* return value size */
1940 func
= PREV_LINK(func
);
1947 static void write_formatstringsdecl(type_t
*iface
)
1949 print_client("#define TYPE_FORMAT_STRING_SIZE %d\n",
1950 get_type_format_string_size(iface
));
1952 print_client("#define PROC_FORMAT_STRING_SIZE %d\n",
1953 get_proc_format_string_size(iface
));
1955 fprintf(client
, "\n");
1956 write_formatdesc("TYPE");
1957 write_formatdesc("PROC");
1958 fprintf(client
, "\n");
1959 print_client("extern const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n");
1960 print_client("extern const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n");
1965 static void write_implicithandledecl(type_t
*iface
)
1967 char *implicit_handle
= get_attrp(iface
->attrs
, ATTR_IMPLICIT_HANDLE
);
1969 if (implicit_handle
)
1971 fprintf(client
, "handle_t %s;\n", implicit_handle
);
1972 fprintf(client
, "\n");
1977 static void init_client(void)
1980 if (!(client
= fopen(client_name
, "w")))
1981 error("Could not open %s for output\n", client_name
);
1983 print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION
, input_name
);
1984 print_client("#include <string.h>\n");
1985 print_client("#ifdef _ALPHA_\n");
1986 print_client("#include <stdarg.h>\n");
1987 print_client("#endif\n");
1988 fprintf(client
, "\n");
1989 print_client("#include \"%s\"\n", header_name
);
1990 fprintf(client
, "\n");
1994 void write_client(ifref_t
*ifaces
)
1996 ifref_t
*iface
= ifaces
;
2010 fprintf(client
, "/*****************************************************************************\n");
2011 fprintf(client
, " * %s interface\n", iface
->iface
->name
);
2012 fprintf(client
, " */\n");
2013 fprintf(client
, "\n");
2015 write_formatstringsdecl(iface
->iface
);
2016 write_implicithandledecl(iface
->iface
);
2018 write_clientinterfacedecl(iface
->iface
);
2019 write_stubdescdecl(iface
->iface
);
2020 write_bindinghandledecl(iface
->iface
);
2022 write_function_stubs(iface
->iface
);
2023 write_stubdescriptor(iface
->iface
);
2025 print_client("#if !defined(__RPC_WIN32__)\n");
2026 print_client("#error Invalid build platform for this stub.\n");
2027 print_client("#endif\n");
2028 fprintf(client
, "\n");
2030 write_procformatstring(iface
->iface
);
2031 write_typeformatstring(iface
->iface
);
2033 fprintf(client
, "\n");
2035 iface
= PREV_LINK(iface
);