ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

client.c
Go to the documentation of this file.
00001 /*
00002  * IDL Compiler
00003  *
00004  * Copyright 2005-2006 Eric Kohl
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 #include "wine/port.h"
00023  
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #ifdef HAVE_UNISTD_H
00027 # include <unistd.h>
00028 #endif
00029 #include <string.h>
00030 #include <ctype.h>
00031 
00032 #include "widl.h"
00033 #include "utils.h"
00034 #include "parser.h"
00035 #include "header.h"
00036 
00037 #include "widltypes.h"
00038 #include "typegen.h"
00039 #include "expr.h"
00040 
00041 static FILE* client;
00042 static int indent = 0;
00043 
00044 static void print_client( const char *format, ... ) __attribute__((format (printf, 1, 2)));
00045 static void print_client( const char *format, ... )
00046 {
00047     va_list va;
00048     va_start(va, format);
00049     print(client, indent, format, va);
00050     va_end(va);
00051 }
00052 
00053 static void write_client_func_decl( const type_t *iface, const var_t *func )
00054 {
00055     const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
00056     const var_list_t *args = type_get_function_args(func->type);
00057     type_t *rettype = type_function_get_rettype(func->type);
00058 
00059     if (!callconv) callconv = "__cdecl";
00060     write_type_decl_left(client, rettype);
00061     fprintf(client, " %s ", callconv);
00062     fprintf(client, "%s%s(\n", prefix_client, get_name(func));
00063     indent++;
00064     if (args)
00065         write_args(client, args, iface->name, 0, TRUE);
00066     else
00067         print_client("void");
00068     fprintf(client, ")\n");
00069     indent--;
00070 }
00071 
00072 static void write_function_stub( const type_t *iface, const var_t *func,
00073                                  int method_count, unsigned int proc_offset )
00074 {
00075     unsigned char explicit_fc, implicit_fc;
00076     int has_full_pointer = is_full_pointer_function(func);
00077     type_t *rettype = type_function_get_rettype(func->type);
00078     const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
00079     int has_ret = !is_void(rettype);
00080 
00081     if (is_interpreted_func( iface, func ))
00082     {
00083         write_client_func_decl( iface, func );
00084         write_client_call_routine( client, iface, func, iface->name, proc_offset );
00085         return;
00086     }
00087 
00088     print_client( "struct __frame_%s%s\n{\n", prefix_client, get_name(func) );
00089     indent++;
00090     print_client( "__DECL_EXCEPTION_FRAME\n" );
00091     print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
00092     if (handle_var)
00093     {
00094         if (explicit_fc == RPC_FC_BIND_GENERIC)
00095             print_client("%s %s;\n",
00096                          get_explicit_generic_handle_type(handle_var)->name, handle_var->name );
00097         print_client("RPC_BINDING_HANDLE _Handle;\n");
00098     }
00099 
00100     if (has_ret && decl_indirect(rettype))
00101     {
00102         print_client("void *_p_%s;\n", "_RetVal" );
00103     }
00104     indent--;
00105     print_client( "};\n\n" );
00106 
00107     print_client( "static void __finally_%s%s(", prefix_client, get_name(func) );
00108     print_client( " struct __frame_%s%s *__frame )\n{\n", prefix_client, get_name(func) );
00109     indent++;
00110 
00111     if (has_full_pointer)
00112         write_full_pointer_free(client, indent, func);
00113 
00114     print_client("NdrFreeBuffer(&__frame->_StubMsg);\n");
00115 
00116     if (explicit_fc == RPC_FC_BIND_GENERIC)
00117     {
00118         fprintf(client, "\n");
00119         print_client("if (__frame->_Handle)\n");
00120         indent++;
00121         print_client("%s_unbind(__frame->%s, __frame->_Handle);\n",
00122                      get_explicit_generic_handle_type(handle_var)->name, handle_var->name);
00123         indent--;
00124     }
00125     indent--;
00126     print_client( "}\n\n" );
00127 
00128     write_client_func_decl( iface, func );
00129 
00130     /* write the functions body */
00131     fprintf(client, "{\n");
00132     indent++;
00133     print_client( "struct __frame_%s%s __f, * const __frame = &__f;\n", prefix_client, get_name(func) );
00134 
00135     /* declare return value '_RetVal' */
00136     if (has_ret)
00137     {
00138         print_client("%s", "");
00139         write_type_decl_left(client, rettype);
00140         fprintf(client, " _RetVal;\n");
00141     }
00142     print_client("RPC_MESSAGE _RpcMessage;\n");
00143 
00144     if (handle_var)
00145     {
00146         print_client( "__frame->_Handle = 0;\n" );
00147         if (explicit_fc == RPC_FC_BIND_GENERIC)
00148             print_client("__frame->%s = %s;\n", handle_var->name, handle_var->name );
00149     }
00150     if (has_ret && decl_indirect(rettype))
00151     {
00152         print_client("__frame->_p_%s = &%s;\n",
00153                      "_RetVal", "_RetVal");
00154     }
00155     fprintf(client, "\n");
00156 
00157     print_client( "RpcExceptionInit( 0, __finally_%s%s );\n", prefix_client, get_name(func) );
00158 
00159     if (has_full_pointer)
00160         write_full_pointer_init(client, indent, func, FALSE);
00161 
00162     /* check pointers */
00163     write_pointer_checks( client, indent, func );
00164 
00165     print_client("RpcTryFinally\n");
00166     print_client("{\n");
00167     indent++;
00168 
00169     print_client("NdrClientInitializeNew(&_RpcMessage, &__frame->_StubMsg, &%s_StubDesc, %d);\n",
00170                  iface->name, method_count);
00171 
00172     if (is_attr(func->attrs, ATTR_IDEMPOTENT) || is_attr(func->attrs, ATTR_BROADCAST))
00173     {
00174         print_client("_RpcMessage.RpcFlags = ( RPC_NCA_FLAGS_DEFAULT ");
00175         if (is_attr(func->attrs, ATTR_IDEMPOTENT))
00176             fprintf(client, "| RPC_NCA_FLAGS_IDEMPOTENT ");
00177         if (is_attr(func->attrs, ATTR_BROADCAST))
00178             fprintf(client, "| RPC_NCA_FLAGS_BROADCAST ");
00179         fprintf(client, ");\n\n");
00180     }
00181 
00182     switch (explicit_fc)
00183     {
00184     case RPC_FC_BIND_PRIMITIVE:
00185         print_client("__frame->_Handle = %s;\n", handle_var->name);
00186         fprintf(client, "\n");
00187         break;
00188     case RPC_FC_BIND_GENERIC:
00189         print_client("__frame->_Handle = %s_bind(%s);\n",
00190                      get_explicit_generic_handle_type(handle_var)->name, handle_var->name);
00191         fprintf(client, "\n");
00192         break;
00193     case RPC_FC_BIND_CONTEXT:
00194     {
00195         /* if the context_handle attribute appears in the chain of types
00196          * without pointers being followed, then the context handle must
00197          * be direct, otherwise it is a pointer */
00198         int is_ch_ptr = !is_aliaschain_attr(handle_var->type, ATTR_CONTEXTHANDLE);
00199         print_client("if (%s%s != 0)\n", is_ch_ptr ? "*" : "", handle_var->name);
00200         indent++;
00201         print_client("__frame->_Handle = NDRCContextBinding(%s%s);\n",
00202                      is_ch_ptr ? "*" : "", handle_var->name);
00203         indent--;
00204         if (is_attr(handle_var->attrs, ATTR_IN) && !is_attr(handle_var->attrs, ATTR_OUT))
00205         {
00206             print_client("else\n");
00207             indent++;
00208             print_client("RpcRaiseException(RPC_X_SS_IN_NULL_CONTEXT);\n");
00209             indent--;
00210         }
00211         fprintf(client, "\n");
00212         break;
00213     }
00214     case 0:  /* implicit handle */
00215         if (handle_var)
00216         {
00217             print_client("__frame->_Handle = %s;\n", handle_var->name);
00218             fprintf(client, "\n");
00219         }
00220         break;
00221     }
00222 
00223     write_remoting_arguments(client, indent, func, "", PASS_IN, PHASE_BUFFERSIZE);
00224 
00225     print_client("NdrGetBuffer(&__frame->_StubMsg, __frame->_StubMsg.BufferLength, ");
00226     if (handle_var)
00227         fprintf(client, "__frame->_Handle);\n\n");
00228     else
00229         fprintf(client,"%s__MIDL_AutoBindHandle);\n\n", iface->name);
00230 
00231     /* marshal arguments */
00232     write_remoting_arguments(client, indent, func, "", PASS_IN, PHASE_MARSHAL);
00233 
00234     /* send/receive message */
00235     /* print_client("NdrNsSendReceive(\n"); */
00236     /* print_client("(unsigned char *)__frame->_StubMsg.Buffer,\n"); */
00237     /* print_client("(RPC_BINDING_HANDLE *) &%s__MIDL_AutoBindHandle);\n", iface->name); */
00238     print_client("NdrSendReceive(&__frame->_StubMsg, __frame->_StubMsg.Buffer);\n\n");
00239 
00240     print_client("__frame->_StubMsg.BufferStart = _RpcMessage.Buffer;\n");
00241     print_client("__frame->_StubMsg.BufferEnd = __frame->_StubMsg.BufferStart + _RpcMessage.BufferLength;\n");
00242 
00243     if (has_out_arg_or_return(func))
00244     {
00245         fprintf(client, "\n");
00246 
00247         print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
00248         indent++;
00249         print_client("NdrConvert(&__frame->_StubMsg, (PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n",
00250                      proc_offset);
00251         indent--;
00252     }
00253 
00254     /* unmarshall arguments */
00255     fprintf(client, "\n");
00256     write_remoting_arguments(client, indent, func, "", PASS_OUT, PHASE_UNMARSHAL);
00257 
00258     /* unmarshal return value */
00259     if (has_ret)
00260     {
00261         if (decl_indirect(rettype))
00262             print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal");
00263         else if (is_ptr(rettype) || is_array(rettype))
00264             print_client("%s = 0;\n", "_RetVal");
00265         write_remoting_arguments(client, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
00266     }
00267 
00268     indent--;
00269     print_client("}\n");
00270     print_client("RpcFinally\n");
00271     print_client("{\n");
00272     indent++;
00273     print_client( "__finally_%s%s( __frame );\n", prefix_client, get_name(func) );
00274     indent--;
00275     print_client("}\n");
00276     print_client("RpcEndFinally\n");
00277 
00278 
00279     /* emit return code */
00280     if (has_ret)
00281     {
00282         fprintf(client, "\n");
00283         print_client("return _RetVal;\n");
00284     }
00285 
00286     indent--;
00287     fprintf(client, "}\n");
00288     fprintf(client, "\n");
00289 }
00290 
00291 static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
00292 {
00293     const statement_t *stmt;
00294     const var_t *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
00295     int method_count = 0;
00296 
00297     if (!implicit_handle)
00298         print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name);
00299 
00300     STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
00301     {
00302         const var_t *func = stmt->u.var;
00303         write_function_stub( iface, func, method_count++, *proc_offset );
00304         *proc_offset += get_size_procformatstring_func( iface, func );
00305     }
00306 }
00307 
00308 
00309 static void write_stubdescdecl(type_t *iface)
00310 {
00311     print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name);
00312     fprintf(client, "\n");
00313 }
00314 
00315 
00316 static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
00317 {
00318     const var_t *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
00319 
00320     print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name);
00321     print_client("{\n");
00322     indent++;
00323     print_client("(void *)& %s___RpcClientInterface,\n", iface->name);
00324     print_client("MIDL_user_allocate,\n");
00325     print_client("MIDL_user_free,\n");
00326     print_client("{\n");
00327     indent++;
00328     if (implicit_handle)
00329         print_client("&%s,\n", implicit_handle->name);
00330     else
00331         print_client("&%s__MIDL_AutoBindHandle,\n", iface->name);
00332     indent--;
00333     print_client("},\n");
00334     print_client("0,\n");
00335     if (!list_empty( &generic_handle_list ))
00336         print_client("BindingRoutines,\n");
00337     else
00338         print_client("0,\n");
00339     if (expr_eval_routines)
00340         print_client("ExprEvalRoutines,\n");
00341     else
00342         print_client("0,\n");
00343     print_client("0,\n");
00344     print_client("__MIDL_TypeFormatString.Format,\n");
00345     print_client("1, /* -error bounds_check flag */\n");
00346     print_client("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
00347     print_client("0,\n");
00348     print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
00349     print_client("0,\n");
00350     print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
00351     print_client("0,  /* notify & notify_flag routine table */\n");
00352     print_client("1,  /* Flags */\n");
00353     print_client("0,  /* Reserved3 */\n");
00354     print_client("0,  /* Reserved4 */\n");
00355     print_client("0   /* Reserved5 */\n");
00356     indent--;
00357     print_client("};\n");
00358     fprintf(client, "\n");
00359 }
00360 
00361 
00362 static void write_clientinterfacedecl(type_t *iface)
00363 {
00364     unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
00365     const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
00366     const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT);
00367 
00368     if (endpoints) write_endpoints( client, iface->name, endpoints );
00369 
00370     print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface->name );
00371     print_client("{\n");
00372     indent++;
00373     print_client("sizeof(RPC_CLIENT_INTERFACE),\n");
00374     print_client("{{0x%08x,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n",
00375                  uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
00376                  uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6],
00377                  uuid->Data4[7], MAJORVERSION(ver), MINORVERSION(ver));
00378     print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */
00379     print_client("0,\n");
00380     if (endpoints)
00381     {
00382         print_client("%u,\n", list_count(endpoints));
00383         print_client("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name);
00384     }
00385     else
00386     {
00387         print_client("0,\n");
00388         print_client("0,\n");
00389     }
00390     print_client("0,\n");
00391     print_client("0,\n");
00392     print_client("0,\n");
00393     indent--;
00394     print_client("};\n");
00395     if (old_names)
00396         print_client("RPC_IF_HANDLE %s_ClientIfHandle DECLSPEC_HIDDEN = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
00397                      iface->name, iface->name);
00398     else
00399         print_client("RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec DECLSPEC_HIDDEN = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
00400                      prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver), iface->name);
00401     fprintf(client, "\n");
00402 }
00403 
00404 
00405 static void write_implicithandledecl(type_t *iface)
00406 {
00407     const var_t *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
00408 
00409     if (implicit_handle)
00410     {
00411         write_type_decl( client, implicit_handle->type, implicit_handle->name );
00412         fprintf(client, ";\n\n");
00413     }
00414 }
00415 
00416 
00417 static void init_client(void)
00418 {
00419     if (client) return;
00420     if (!(client = fopen(client_name, "w")))
00421         error("Could not open %s for output\n", client_name);
00422 
00423     print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
00424     print_client("#include <string.h>\n");
00425     print_client( "\n");
00426     print_client("#include \"%s\"\n", header_name);
00427     print_client( "\n");
00428     print_client( "#ifndef DECLSPEC_HIDDEN\n");
00429     print_client( "#define DECLSPEC_HIDDEN\n");
00430     print_client( "#endif\n");
00431     print_client( "\n");
00432 }
00433 
00434 
00435 static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_routines, unsigned int *proc_offset)
00436 {
00437     const statement_t *stmt;
00438     if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
00439     {
00440         if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
00441         {
00442             int has_func = 0;
00443             const statement_t *stmt2;
00444             type_t *iface = stmt->u.type;
00445             if (!need_stub(iface))
00446                 return;
00447 
00448             fprintf(client, "/*****************************************************************************\n");
00449             fprintf(client, " * %s interface\n", iface->name);
00450             fprintf(client, " */\n");
00451             fprintf(client, "\n");
00452 
00453             STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface))
00454             {
00455                 has_func = 1;
00456                 break;
00457             }
00458 
00459             if (has_func)
00460             {
00461                 write_implicithandledecl(iface);
00462 
00463                 write_clientinterfacedecl(iface);
00464                 write_stubdescdecl(iface);
00465                 write_function_stubs(iface, proc_offset);
00466 
00467                 print_client("#if !defined(__RPC_WIN%u__)\n", pointer_size == 8 ? 64 : 32);
00468                 print_client("#error  Invalid build platform for this stub.\n");
00469                 print_client("#endif\n");
00470 
00471                 fprintf(client, "\n");
00472                 write_stubdescriptor(iface, expr_eval_routines);
00473             }
00474         }
00475         else if (stmt->type == STMT_LIBRARY)
00476             write_client_ifaces(stmt->u.lib->stmts, expr_eval_routines, proc_offset);
00477     }
00478 }
00479 
00480 static void write_generic_handle_routine_list(void)
00481 {
00482     generic_handle_t *gh;
00483 
00484     if (list_empty( &generic_handle_list )) return;
00485     print_client( "static const GENERIC_BINDING_ROUTINE_PAIR BindingRoutines[] =\n" );
00486     print_client( "{\n" );
00487     indent++;
00488     LIST_FOR_EACH_ENTRY( gh, &generic_handle_list, generic_handle_t, entry )
00489     {
00490         print_client( "{ (GENERIC_BINDING_ROUTINE)%s_bind, (GENERIC_UNBIND_ROUTINE)%s_unbind },\n",
00491                       gh->name, gh->name );
00492     }
00493     indent--;
00494     print_client( "};\n\n" );
00495 }
00496 
00497 static void write_client_routines(const statement_list_t *stmts)
00498 {
00499     unsigned int proc_offset = 0;
00500     int expr_eval_routines;
00501 
00502     if (need_inline_stubs_file( stmts ))
00503     {
00504         write_exceptions( client );
00505         print_client( "\n");
00506     }
00507 
00508     write_formatstringsdecl(client, indent, stmts, need_stub);
00509     expr_eval_routines = write_expr_eval_routines(client, client_token);
00510     if (expr_eval_routines)
00511         write_expr_eval_routine_list(client, client_token);
00512     write_generic_handle_routine_list();
00513     write_user_quad_list(client);
00514 
00515     write_client_ifaces(stmts, expr_eval_routines, &proc_offset);
00516 
00517     fprintf(client, "\n");
00518 
00519     write_procformatstring(client, stmts, need_stub);
00520     write_typeformatstring(client, stmts, need_stub);
00521 }
00522 
00523 void write_client(const statement_list_t *stmts)
00524 {
00525     if (!do_client)
00526         return;
00527     if (do_everything && !need_stub_files(stmts))
00528         return;
00529 
00530     init_client();
00531     if (!client)
00532         return;
00533 
00534     if (do_win32 && do_win64)
00535     {
00536         fprintf(client, "#ifndef _WIN64\n\n");
00537         pointer_size = 4;
00538         write_client_routines( stmts );
00539         fprintf(client, "\n#else /* _WIN64 */\n\n");
00540         pointer_size = 8;
00541         write_client_routines( stmts );
00542         fprintf(client, "\n#endif /* _WIN64 */\n");
00543     }
00544     else if (do_win32)
00545     {
00546         pointer_size = 4;
00547         write_client_routines( stmts );
00548     }
00549     else if (do_win64)
00550     {
00551         pointer_size = 8;
00552         write_client_routines( stmts );
00553     }
00554 
00555     fclose(client);
00556 }

Generated on Sat May 26 2012 04:24:50 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.