Generate some marshalling code for stubs.
[wine/multimedia.git] / tools / widl / proxy.c
blob95faabd6daccae5963b1db210c233be271368966
1 /*
2 * IDL Compiler
4 * Copyright 2002 Ove Kaaven
5 * Copyright 2004 Mike McCormack
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 #include <string.h>
30 #include <assert.h>
31 #include <ctype.h>
32 #include <signal.h>
34 #include "widl.h"
35 #include "utils.h"
36 #include "parser.h"
37 #include "header.h"
39 static FILE* proxy;
40 static int indent = 0;
42 /* FIXME: support generation of stubless proxies */
44 int print_proxy( char *format, ... )
46 va_list va;
47 int i, r;
49 va_start( va, format );
50 for( i=0; i<indent; i++ )
51 fprintf( proxy, " " );
52 r = vfprintf( proxy, format, va );
53 va_end( va );
54 return r;
57 static type_t *get_base_type( type_t *type )
59 while( type->ref )
60 type = type->ref;
61 return type;
64 static void write_stubdescproto(void)
66 print_proxy( "extern const MIDL_STUB_DESC Object_StubDesc;\n");
67 print_proxy( "\n");
70 static void write_stubdesc(void)
72 print_proxy( "const MIDL_STUB_DESC Object_StubDesc = {\n");
73 print_proxy( " 0,\n");
74 print_proxy( " NdrOleAllocate,\n");
75 print_proxy( " NdrOleFree,\n");
76 print_proxy( " {0}, 0, 0, 0, 0,\n");
77 print_proxy( " 0 /* __MIDL_TypeFormatString.Format */\n");
78 print_proxy( "};\n");
79 print_proxy( "\n");
82 static void write_formatdesc( char *str )
84 print_proxy( "typedef struct _MIDL_%s_FORMAT_STRING {\n", str );
85 print_proxy( " short Pad;\n");
86 print_proxy( " unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str);
87 print_proxy( "} MIDL_%s_FORMAT_STRING;\n", str);
88 print_proxy( "\n");
91 static void write_formatstringsdecl(void)
93 print_proxy( "#define TYPE_FORMAT_STRING_SIZE %d\n",1); /* FIXME */
94 print_proxy( "#define PROC_FORMAT_STRING_SIZE %d\n",1); /* FIXME */
95 print_proxy( "\n");
96 write_formatdesc( "TYPE" );
97 write_formatdesc( "PROC" );
98 print_proxy( "extern const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n");
99 print_proxy( "extern const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n");
100 print_proxy( "\n");
103 static void write_formatstring( int proc )
105 const char *t, *n;
106 if( !proc )
108 t = "TYPE";
109 n = "Type";
111 else
113 t = "PROC";
114 n = "Proc";
116 print_proxy( "static const MIDL_%s_FORMAT_STRING __MIDL_%sFormatString =\n", t, n);
117 print_proxy( "{\n");
118 indent++;
119 print_proxy( "0,\n");
120 print_proxy( "{\n");
121 indent++;
122 print_proxy( "0\n");
123 indent--;
124 print_proxy( "}\n");
125 indent--;
126 print_proxy( "};\n");
127 print_proxy( "\n");
130 static void init_proxy(void)
132 if (proxy) return;
133 proxy = fopen(proxy_name, "w");
134 print_proxy( "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION);
135 print_proxy( "\n");
136 print_proxy( "#ifndef __REDQ_RPCPROXY_H_VERSION__\n");
137 print_proxy( "#define __REQUIRED_RPCPROXY_H_VERSION__ 440\n");
138 print_proxy( "#endif /* __REDQ_RPCPROXY_H_VERSION__ */\n");
139 print_proxy( "\n");
140 print_proxy( "#include \"rpcproxy.h\"\n");
141 print_proxy( "\n");
142 print_proxy( "#ifndef __RPCPROXY_H_VERSION__\n");
143 print_proxy( "#error This code needs a newer version of rpcproxy.h\n");
144 print_proxy( "#endif /* __RPCPROXY_H_VERSION__ */\n");
145 print_proxy( "\n");
146 print_proxy( "#include \"%s\"\n", header_name);
147 print_proxy( "\n");
148 write_formatstringsdecl();
149 write_stubdescproto();
152 static void clear_output_vars( var_t *arg )
154 if (arg) {
155 while (NEXT_LINK(arg))
156 arg = NEXT_LINK(arg);
158 while (arg) {
159 if (is_attr(arg->attrs, ATTR_OUT) && !is_attr(arg->attrs, ATTR_IN)) {
160 print_proxy( "if(%s)\n", arg->name );
161 indent++;
162 print_proxy( "MIDL_memset( %s, 0, sizeof( ", arg->name );
163 indent--;
164 write_type(proxy, arg->type, arg, arg->tname);
165 fprintf( proxy, " ));\n" );
167 arg = PREV_LINK(arg);
171 static void proxy_gen_marshall_size( var_t *arg )
173 print_proxy( "_StubMsg.BufferLength = 0U;\n" );
175 if (arg) {
176 while (NEXT_LINK(arg))
177 arg = NEXT_LINK(arg);
179 while (arg) {
180 if (is_attr(arg->attrs, ATTR_IN)) {
181 int index = 0;
182 type_t *type = get_base_type(arg->type);
184 switch( type->type )
186 case RPC_FC_BYTE:
187 case RPC_FC_CHAR:
188 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 1, arg->name );
189 break;
191 case RPC_FC_SHORT:
192 case RPC_FC_USHORT:
193 case RPC_FC_ENUM16:
194 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 2, arg->name );
195 break;
197 case RPC_FC_LONG:
198 case RPC_FC_ULONG:
199 case RPC_FC_ENUM32:
200 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 4, arg->name );
201 break;
203 case RPC_FC_STRUCT:
204 print_proxy( "NdrSimpleStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name );
205 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index );
206 break;
208 case RPC_FC_IP:
209 print_proxy( "NdrPointerBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name );
210 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
211 break;
213 default:
214 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
217 arg = PREV_LINK(arg);
221 static void gen_marshall_copydata( var_t *arg )
223 if (arg) {
224 while (NEXT_LINK(arg))
225 arg = NEXT_LINK(arg);
227 while (arg) {
228 if (is_attr(arg->attrs, ATTR_IN)) {
229 int index = 0;
230 type_t *type = get_base_type(arg->type);
232 switch( type->type )
234 case RPC_FC_BYTE:
235 case RPC_FC_CHAR:
236 case RPC_FC_SHORT:
237 case RPC_FC_USHORT:
238 case RPC_FC_ENUM16:
239 case RPC_FC_LONG:
240 case RPC_FC_ULONG:
241 case RPC_FC_ENUM32:
242 print_proxy( "*((");
243 write_type(proxy, arg->type, arg, arg->tname);
244 fprintf(proxy,"*)_StubMsg.Buffer)++ = %s;\n", arg->name );
245 break;
247 case RPC_FC_STRUCT:
248 /* FIXME: add the format string, and set the index below */
249 print_proxy( "NdrSimpleStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name );
250 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
251 break;
253 case RPC_FC_IP:
254 print_proxy( "NdrPointerMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name );
255 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
256 break;
258 default:
259 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
262 arg = PREV_LINK(arg);
266 static void gen_marshall( var_t *arg )
268 /* generated code to determine the size of the buffer required */
269 proxy_gen_marshall_size( arg );
271 /* generated code to allocate the buffer */
272 print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" );
274 /* generated code to copy the args into the buffer */
275 gen_marshall_copydata( arg );
277 print_proxy( "\n");
280 static void gen_unmarshall( var_t *arg )
282 if (arg) {
283 while (NEXT_LINK(arg))
284 arg = NEXT_LINK(arg);
286 while (arg) {
287 if (is_attr(arg->attrs, ATTR_IN)) {
288 int index = 0;
289 print_proxy( "NdrPointerUnmarshall(&_StubMsg, (unsigned char**)&%s, ", arg->name );
290 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index );
292 arg = PREV_LINK(arg);
296 static void gen_proxy(type_t *iface, func_t *cur, int idx)
298 var_t *def = cur->def;
299 int has_ret = !is_void(def->type, def);
301 indent = 0;
302 write_type(proxy, def->type, def, def->tname);
303 print_proxy( " CALLBACK %s_", iface->name);
304 write_name(proxy, def);
305 print_proxy( "_Proxy(\n");
306 write_args(proxy, cur->args, iface->name, 1, TRUE);
307 print_proxy( ")\n");
308 print_proxy( "{\n");
309 indent ++;
310 /* local variables */
311 if (has_ret) {
312 print_proxy( "" );
313 write_type(proxy, def->type, def, def->tname);
314 print_proxy( " _Ret;\n");
316 print_proxy( "RPC_MESSAGE _Msg;\n" );
317 print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" );
318 print_proxy( "\n");
320 /* FIXME: trace */
321 clear_output_vars( cur->args );
323 print_proxy( "RpcTryExcept\n" );
324 print_proxy( "{\n" );
325 indent++;
326 print_proxy( "NdrProxyInitialize(This, &_Msg, &_StubMsg, &Object_StubDesc, %d);\n", idx);
328 print_proxy( "RpcTryFinally\n" );
329 print_proxy( "{\n" );
330 indent++;
332 gen_marshall( cur->args );
334 print_proxy( "NdrProxySendReceive(This, &_StubMsg);\n" );
335 print_proxy( "\n");
337 gen_unmarshall( cur->args );
338 if (has_ret) {
340 * FIXME: We only need to round the buffer up if it could be unaligned...
341 * We should calculate how much buffer we used and output the following
342 * line only if necessary.
344 print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n");
346 print_proxy( "_Ret = *((" );
347 write_type(proxy, def->type, def, def->tname);
348 fprintf(proxy, "*)_StubMsg.Buffer)++;\n");
351 indent--;
352 print_proxy( "}\n");
353 print_proxy( "RpcFinally\n" );
354 print_proxy( "{\n" );
355 indent++;
356 print_proxy( "NdrProxyFreeBuffer(This, &_StubMsg);\n" );
357 indent--;
358 print_proxy( "}\n");
359 print_proxy( "RpcEndFinally\n" );
360 indent--;
361 print_proxy( "}\n" );
362 print_proxy( "RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE)\n" );
363 print_proxy( "{\n" );
364 if (has_ret) {
365 indent++;
366 print_proxy( "_Ret = NdrProxyErrorHandler(RpcExceptionCode());\n" );
367 indent--;
369 print_proxy( "}\n" );
370 print_proxy( "RpcEndExcept\n" );
372 if (has_ret) {
373 print_proxy( "return _Ret;\n" );
375 indent--;
376 print_proxy( "}\n");
377 print_proxy( "\n");
380 static void stub_clear_output_vars( var_t *arg )
382 while (arg) {
383 print_proxy("(");
384 write_type(proxy, arg->type, arg, arg->tname);
385 fprintf(proxy, ") ");
386 write_name(proxy, arg);
387 fprintf(proxy, " = 0;\n");
388 arg = NEXT_LINK(arg);
390 fprintf(proxy, "\n");
393 static void stub_unmarshall( var_t *arg )
395 if (arg) {
396 while (NEXT_LINK(arg))
397 arg = NEXT_LINK(arg);
399 while (arg) {
400 if (is_attr(arg->attrs, ATTR_IN)) {
401 int index = 0;
402 type_t *type = get_base_type(arg->type);
404 switch( type->type )
406 case RPC_FC_BYTE:
407 case RPC_FC_CHAR:
408 case RPC_FC_SHORT:
409 case RPC_FC_USHORT:
410 case RPC_FC_ENUM16:
411 case RPC_FC_LONG:
412 case RPC_FC_ULONG:
413 case RPC_FC_ENUM32:
414 print_proxy( "%s = *((", arg->name);
415 write_type(proxy, arg->type, arg, arg->tname);
416 fprintf(proxy,"*)_StubMsg.Buffer)++;\n");
417 break;
419 case RPC_FC_STRUCT:
420 /* FIXME: add the format string, and set the index below */
421 print_proxy( "NdrSimpleStructUnmarshall(&_StubMsg, (unsigned char**)&%s, ", arg->name );
422 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d],0);\n", index );
423 break;
425 default:
426 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
429 arg = PREV_LINK(arg);
433 static void stub_gen_marshall_size( var_t *arg )
435 print_proxy( "_StubMsg.BufferLength = 0U;\n" );
437 if (arg) {
438 while (NEXT_LINK(arg))
439 arg = NEXT_LINK(arg);
441 while (arg) {
442 if (is_attr(arg->attrs, ATTR_OUT)) {
443 int index = 0;
444 type_t *type = get_base_type(arg->type);
446 switch( type->type )
448 case RPC_FC_BYTE:
449 case RPC_FC_CHAR:
450 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 1, arg->name );
451 break;
453 case RPC_FC_SHORT:
454 case RPC_FC_USHORT:
455 case RPC_FC_ENUM16:
456 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 2, arg->name );
457 break;
459 case RPC_FC_LONG:
460 case RPC_FC_ULONG:
461 case RPC_FC_ENUM32:
462 print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 4, arg->name );
463 break;
465 case RPC_FC_STRUCT:
466 print_proxy( "NdrSimpleStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name );
467 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index );
468 break;
470 case RPC_FC_IP:
471 print_proxy( "NdrPointerBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name );
472 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
473 break;
475 default:
476 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
479 arg = PREV_LINK(arg);
483 static void stub_gen_marshall_copydata( var_t *arg )
485 if (arg) {
486 while (NEXT_LINK(arg))
487 arg = NEXT_LINK(arg);
489 while (arg) {
490 if (is_attr(arg->attrs, ATTR_OUT)) {
491 int index = 0;
492 type_t *type = get_base_type(arg->type);
494 switch( type->type )
496 case RPC_FC_BYTE:
497 case RPC_FC_CHAR:
498 case RPC_FC_SHORT:
499 case RPC_FC_USHORT:
500 case RPC_FC_ENUM16:
501 case RPC_FC_LONG:
502 case RPC_FC_ULONG:
503 case RPC_FC_ENUM32:
504 print_proxy( "*((");
505 write_type(proxy, arg->type, arg, arg->tname);
506 fprintf(proxy,"*)_StubMsg.Buffer)++ = %s;\n", arg->name );
507 break;
509 case RPC_FC_STRUCT:
510 /* FIXME: add the format string, and set the index below */
511 print_proxy( "NdrSimpleStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name );
512 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
513 break;
515 case RPC_FC_IP:
516 print_proxy( "NdrPointerMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name );
517 fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
518 break;
520 default:
521 printf("FIXME: arg %s has unknown type %d\n", arg->name, type->type );
524 arg = PREV_LINK(arg);
528 static void stub_genmarshall( var_t *args )
530 /* FIXME: size buffer */
531 stub_gen_marshall_size( args );
533 print_proxy("NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n");
535 stub_gen_marshall_copydata( args );
538 static void gen_stub(type_t *iface, func_t *cur, char *cas)
540 var_t *def = cur->def;
541 var_t *arg;
542 int has_ret = !is_void(def->type, def);
544 indent = 0;
545 print_proxy( "void __RPC_STUB %s_", iface->name);
546 write_name(proxy, def);
547 print_proxy( "_Stub(\n");
548 indent++;
549 print_proxy( "IRpcStubBuffer* This,\n");
550 print_proxy( "IRpcChannelBuffer* pRpcChannelBuffer,\n");
551 print_proxy( "PRPC_MESSAGE pRpcMessage,\n");
552 print_proxy( "DWORD* pdwStubPhase)\n");
553 indent--;
554 print_proxy( "{\n");
555 indent++;
556 /* local variables */
557 if (has_ret) {
558 print_proxy("");
559 write_type(proxy, def->type, def, def->tname);
560 fprintf(proxy, " _Ret;\n");
562 print_proxy("%s* _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name);
563 print_proxy("MIDL_STUB_MESSAGE _StubMsg;\n");
564 arg = cur->args;
565 while (arg) {
566 print_proxy("");
567 write_type(proxy, arg->type, arg, arg->tname);
568 fprintf(proxy, " ");
569 write_name(proxy, arg);
570 fprintf(proxy, ";\n");
571 arg = NEXT_LINK(arg);
573 fprintf(proxy, "\n");
575 /* FIXME: trace */
577 print_proxy("NdrStubInitialize(pRpcMessage, &_StubMsg, &Object_StubDesc, pRpcChannelBuffer);\n");
578 fprintf(proxy, "\n");
580 print_proxy("RpcTryFinally\n");
581 print_proxy("{\n");
582 indent++;
583 stub_clear_output_vars( cur->args );
585 stub_unmarshall( cur->args );
587 print_proxy("*pdwStubPhase = STUB_CALL_SERVER;\n");
588 print_proxy("");
589 if (has_ret) fprintf(proxy, "_Ret = ");
590 fprintf(proxy, "%s_", iface->name);
591 if (cas) fprintf(proxy, "%s_Stub", cas);
592 else write_name(proxy, def);
593 fprintf(proxy, "(_This");
594 arg = cur->args;
595 if (arg) {
596 while (NEXT_LINK(arg)) arg = NEXT_LINK(arg);
597 while (arg) {
598 fprintf(proxy, ", ");
599 write_name(proxy, arg);
600 arg = PREV_LINK(arg);
603 fprintf(proxy, ");\n");
604 print_proxy("*pdwStubPhase = STUB_MARSHAL;\n");
606 stub_genmarshall( cur->args );
608 if (has_ret) {
610 * FIXME: We only need to round the buffer up if it could be unaligned...
611 * We should calculate how much buffer we used and output the following
612 * line only if necessary.
614 print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n");
616 print_proxy( "*((" );
617 write_type(proxy, def->type, def, def->tname);
618 fprintf(proxy, "*)_StubMsg.Buffer)++ = _Ret;\n");
621 indent--;
622 print_proxy("}\n");
623 print_proxy("RpcFinally\n");
624 print_proxy("{\n");
625 print_proxy("}\n");
626 print_proxy("RpcEndFinally\n");
628 /* FIXME: marshall */
629 indent--;
631 print_proxy("}\n");
632 print_proxy("\n");
635 static int write_proxy_methods(type_t *iface)
637 func_t *cur = iface->funcs;
638 int i = 0;
639 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
641 if (iface->ref) i = write_proxy_methods(iface->ref);
642 while (cur) {
643 var_t *def = cur->def;
644 if (!is_callas(def->attrs)) {
645 if (i) fprintf(proxy, ",\n ");
646 fprintf(proxy, "%s_", iface->name);
647 write_name(proxy, def);
648 fprintf(proxy, "_Proxy");
649 i++;
651 cur = PREV_LINK(cur);
653 return i;
656 static int write_stub_methods(type_t *iface)
658 func_t *cur = iface->funcs;
659 int i = 0;
660 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
662 if (iface->ref) i = write_stub_methods(iface->ref);
663 else return i; /* skip IUnknown */
664 while (cur) {
665 var_t *def = cur->def;
666 if (!is_local(def->attrs)) {
667 if (i) fprintf(proxy, ",\n");
668 fprintf(proxy, " %s_", iface->name);
669 write_name(proxy, def);
670 fprintf(proxy, "_Stub");
671 i++;
673 cur = PREV_LINK(cur);
675 return i;
678 static void write_proxy(type_t *iface)
680 int midx = -1, stubs;
681 func_t *cur = iface->funcs;
683 if (!cur) return;
684 if (!do_everything) return;
686 while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
688 /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */
690 init_proxy();
692 fprintf(proxy, "/*****************************************************************************\n");
693 fprintf(proxy, " * %s interface\n", iface->name);
694 fprintf(proxy, " */\n");
695 while (cur) {
696 var_t *def = cur->def;
697 if (!is_local(def->attrs)) {
698 var_t *cas = is_callas(def->attrs);
699 char *cname = cas ? cas->name : NULL;
700 int idx = cur->idx;
701 if (cname) {
702 func_t *m = iface->funcs;
703 while (m && strcmp(get_name(m->def), cname))
704 m = NEXT_LINK(m);
705 idx = m->idx;
707 gen_proxy(iface, cur, idx);
708 gen_stub(iface, cur, cname);
709 if (midx == -1) midx = idx;
710 else if (midx != idx) yyerror("method index mismatch in write_proxy");
711 midx++;
713 cur = PREV_LINK(cur);
716 write_stubdesc();
718 /* proxy vtable */
719 fprintf(proxy, "const CINTERFACE_PROXY_VTABLE(%d) %sProxyVtbl =\n", midx, iface->name);
720 fprintf(proxy, "{\n");
721 fprintf(proxy, " {&IID_%s},\n", iface->name);
722 fprintf(proxy, " {");
723 write_proxy_methods(iface);
724 fprintf(proxy, "}\n");
725 fprintf(proxy, "};\n");
726 fprintf(proxy, "\n");
728 /* stub vtable */
729 fprintf(proxy, "static const PRPC_STUB_FUNCTION %s_table[] =\n", iface->name);
730 fprintf(proxy, "{\n");
731 stubs = write_stub_methods(iface);
732 fprintf(proxy, "\n");
733 fprintf(proxy, "};\n");
734 fprintf(proxy, "\n");
735 fprintf(proxy, "const CInterfaceStubVtbl %sStubVtbl = {\n", iface->name);
736 fprintf(proxy, " {&IID_%s,\n", iface->name);
737 fprintf(proxy, " 0,\n");
738 fprintf(proxy, " %d,\n", stubs+3);
739 fprintf(proxy, " &%s_table[-3]},\n", iface->name);
740 fprintf(proxy, " {CStdStubBuffer_METHODS}\n");
741 fprintf(proxy, "};\n");
742 fprintf(proxy, "\n");
743 write_formatstring( 1 );
744 write_formatstring( 0 );
747 void write_proxies(ifref_t *ifaces)
749 ifref_t *lcur = ifaces;
750 ifref_t *cur;
751 char *file_id = proxy_token;
752 int c;
754 if (!lcur) return;
755 while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur);
757 cur = lcur;
758 while (cur) {
759 if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs))
760 write_proxy(cur->iface);
761 cur = PREV_LINK(cur);
764 if (!proxy) return;
766 fprintf(proxy, "const CInterfaceProxyVtbl* _%s_ProxyVtblList[] =\n", file_id);
767 fprintf(proxy, "{\n");
768 cur = lcur;
769 while (cur) {
770 if(cur->iface->ref)
771 fprintf(proxy, " (CInterfaceProxyVtbl*)&%sProxyVtbl,\n", cur->iface->name);
772 cur = PREV_LINK(cur);
774 fprintf(proxy, " 0\n");
775 fprintf(proxy, "};\n");
776 fprintf(proxy, "\n");
778 fprintf(proxy, "const CInterfaceStubVtbl* _%s_StubVtblList[] =\n", file_id);
779 fprintf(proxy, "{\n");
780 cur = lcur;
781 while (cur) {
782 if(cur->iface->ref)
783 fprintf(proxy, " (CInterfaceStubVtbl*)&%sStubVtbl,\n", cur->iface->name);
784 cur = PREV_LINK(cur);
786 fprintf(proxy, " 0\n");
787 fprintf(proxy, "};\n");
788 fprintf(proxy, "\n");
790 fprintf(proxy, "const PCInterfaceName _%s_InterfaceNamesList[] =\n", file_id);
791 fprintf(proxy, "{\n");
792 cur = lcur;
793 while (cur) {
794 if(cur->iface->ref)
795 fprintf(proxy, " \"%s\",\n", cur->iface->name);
796 cur = PREV_LINK(cur);
798 fprintf(proxy, " 0\n");
799 fprintf(proxy, "};\n");
800 fprintf(proxy, "\n");
802 fprintf(proxy, "#define _%s_CHECK_IID(n) IID_GENERIC_CHECK_IID(_%s, pIID, n)\n", file_id, file_id);
803 fprintf(proxy, "\n");
804 fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id);
805 fprintf(proxy, "{\n");
806 cur = lcur;
807 c = 0;
808 while (cur) {
809 if(cur->iface->ref)
811 fprintf(proxy, " if (!_%s_CHECK_IID(%d)) {\n", file_id, c);
812 fprintf(proxy, " *pIndex = %d;\n", c);
813 fprintf(proxy, " return 1;\n");
814 fprintf(proxy, " }\n");
815 c++;
817 cur = PREV_LINK(cur);
819 fprintf(proxy, " return 0;\n");
820 fprintf(proxy, "}\n");
821 fprintf(proxy, "\n");
823 fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo =\n", file_id);
824 fprintf(proxy, "{\n");
825 fprintf(proxy, " (PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id);
826 fprintf(proxy, " (PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id);
827 fprintf(proxy, " (const PCInterfaceName*)&_%s_InterfaceNamesList,\n", file_id);
828 fprintf(proxy, " 0,\n");
829 fprintf(proxy, " &_%s_IID_Lookup,\n", file_id);
830 fprintf(proxy, " %d,\n", c);
831 fprintf(proxy, " 1,\n");
832 fprintf(proxy, " 0,\n");
833 fprintf(proxy, " 0,\n");
834 fprintf(proxy, " 0,\n");
835 fprintf(proxy, " 0\n");
836 fprintf(proxy, "};\n");
838 fclose(proxy);