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

server.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 "typegen.h"
00038 
00039 static FILE* server;
00040 static int indent = 0;
00041 
00042 
00043 static void print_server(const char *format, ...) __attribute__((format (printf, 1, 2)));
00044 static void print_server(const char *format, ...)
00045 {
00046     va_list va;
00047     va_start(va, format);
00048     print(server, indent, format, va);
00049     va_end(va);
00050 }
00051 
00052 static void write_function_stub(const type_t *iface, const var_t *func, unsigned int proc_offset)
00053 {
00054     const var_t *var;
00055     unsigned char explicit_fc, implicit_fc;
00056     int has_full_pointer = is_full_pointer_function(func);
00057     const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
00058 
00059     if (is_interpreted_func( iface, func )) return;
00060 
00061     print_server("struct __frame_%s_%s\n{\n", iface->name, get_name(func));
00062     indent++;
00063     print_server("__DECL_EXCEPTION_FRAME\n");
00064     print_server("MIDL_STUB_MESSAGE _StubMsg;\n");
00065 
00066     /* Declare arguments */
00067     declare_stub_args(server, indent, func);
00068 
00069     indent--;
00070     print_server("};\n\n");
00071 
00072     print_server("static void __finally_%s_%s(", iface->name, get_name(func));
00073     fprintf(server," struct __frame_%s_%s *__frame )\n{\n", iface->name, get_name(func));
00074 
00075     indent++;
00076     write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE);
00077 
00078     if (!is_void(type_function_get_rettype(func->type)))
00079         write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE);
00080 
00081     if (has_full_pointer)
00082         write_full_pointer_free(server, indent, func);
00083 
00084     indent--;
00085     print_server("}\n\n");
00086 
00087     print_server("void __RPC_STUB %s_%s( PRPC_MESSAGE _pRpcMessage )\n", iface->name, get_name(func));
00088 
00089     /* write the functions body */
00090     fprintf(server, "{\n");
00091     indent++;
00092     print_server("struct __frame_%s_%s __f, * const __frame = &__f;\n", iface->name, get_name(func));
00093     if (has_out_arg_or_return(func)) print_server("RPC_STATUS _Status;\n");
00094     fprintf(server, "\n");
00095 
00096     print_server("NdrServerInitializeNew(\n");
00097     indent++;
00098     print_server("_pRpcMessage,\n");
00099     print_server("&__frame->_StubMsg,\n");
00100     print_server("&%s_StubDesc);\n", iface->name);
00101     indent--;
00102     fprintf(server, "\n");
00103     print_server( "RpcExceptionInit( __server_filter, __finally_%s_%s );\n", iface->name, get_name(func));
00104 
00105     write_parameters_init(server, indent, func, "__frame->");
00106 
00107     if (explicit_fc == RPC_FC_BIND_PRIMITIVE)
00108     {
00109         print_server("__frame->%s = _pRpcMessage->Handle;\n", handle_var->name);
00110         fprintf(server, "\n");
00111     }
00112 
00113     print_server("RpcTryFinally\n");
00114     print_server("{\n");
00115     indent++;
00116     print_server("RpcTryExcept\n");
00117     print_server("{\n");
00118     indent++;
00119 
00120     if (has_full_pointer)
00121         write_full_pointer_init(server, indent, func, TRUE);
00122 
00123     if (type_get_function_args(func->type))
00124     {
00125         print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
00126         indent++;
00127         print_server("NdrConvert(&__frame->_StubMsg, (PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n",
00128                      proc_offset);
00129         indent--;
00130         fprintf(server, "\n");
00131 
00132         /* unmarshall arguments */
00133         write_remoting_arguments(server, indent, func, "__frame->", PASS_IN, PHASE_UNMARSHAL);
00134     }
00135 
00136     print_server("if (__frame->_StubMsg.Buffer > __frame->_StubMsg.BufferEnd)\n");
00137     print_server("{\n");
00138     indent++;
00139     print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
00140     indent--;
00141     print_server("}\n");
00142     indent--;
00143     print_server("}\n");
00144     print_server("RpcExcept(RPC_BAD_STUB_DATA_EXCEPTION_FILTER)\n");
00145     print_server("{\n");
00146     indent++;
00147     print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
00148     indent--;
00149     print_server("}\n");
00150     print_server("RpcEndExcept\n");
00151     fprintf(server, "\n");
00152 
00153     /* Assign 'out' arguments */
00154     assign_stub_out_args(server, indent, func, "__frame->");
00155 
00156     /* Call the real server function */
00157     print_server("%s%s%s",
00158                  is_void(type_function_get_rettype(func->type)) ? "" : "__frame->_RetVal = ",
00159                  prefix_server, get_name(func));
00160 
00161     if (type_get_function_args(func->type))
00162     {
00163         int first_arg = 1;
00164 
00165         fprintf(server, "(\n");
00166         indent++;
00167         LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
00168         {
00169             if (first_arg)
00170                 first_arg = 0;
00171             else
00172                 fprintf(server, ",\n");
00173             if (is_context_handle(var->type))
00174             {
00175                 /* if the context_handle attribute appears in the chain of types
00176                  * without pointers being followed, then the context handle must
00177                  * be direct, otherwise it is a pointer */
00178                 int is_ch_ptr = is_aliaschain_attr(var->type, ATTR_CONTEXTHANDLE) ? FALSE : TRUE;
00179                 print_server("(");
00180                 write_type_decl_left(server, var->type);
00181                 fprintf(server, ")%sNDRSContextValue(__frame->%s)",
00182                         is_ch_ptr ? "" : "*", var->name);
00183             }
00184             else
00185             {
00186                 print_server("%s__frame->%s", is_array(var->type) && !type_array_is_decl_as_ptr(var->type) ? "*" : "", var->name);
00187             }
00188         }
00189         fprintf(server, ");\n");
00190         indent--;
00191     }
00192     else
00193     {
00194         fprintf(server, "();\n");
00195     }
00196 
00197     if (has_out_arg_or_return(func))
00198     {
00199         write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
00200 
00201         if (!is_void(type_function_get_rettype(func->type)))
00202             write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
00203 
00204         print_server("_pRpcMessage->BufferLength = __frame->_StubMsg.BufferLength;\n");
00205         fprintf(server, "\n");
00206         print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");
00207         print_server("if (_Status)\n");
00208         indent++;
00209         print_server("RpcRaiseException(_Status);\n");
00210         indent--;
00211         fprintf(server, "\n");
00212         print_server("__frame->_StubMsg.Buffer = _pRpcMessage->Buffer;\n");
00213         fprintf(server, "\n");
00214     }
00215 
00216     /* marshall arguments */
00217     write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_MARSHAL);
00218 
00219     /* marshall the return value */
00220     if (!is_void(type_function_get_rettype(func->type)))
00221         write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
00222 
00223     indent--;
00224     print_server("}\n");
00225     print_server("RpcFinally\n");
00226     print_server("{\n");
00227     indent++;
00228     print_server("__finally_%s_%s( __frame );\n", iface->name, get_name(func));
00229     indent--;
00230     print_server("}\n");
00231     print_server("RpcEndFinally\n");
00232 
00233     /* calculate buffer length */
00234     fprintf(server, "\n");
00235     print_server("_pRpcMessage->BufferLength = __frame->_StubMsg.Buffer - (unsigned char *)_pRpcMessage->Buffer;\n");
00236     indent--;
00237     fprintf(server, "}\n");
00238     fprintf(server, "\n");
00239 }
00240 
00241 
00242 static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
00243 {
00244     const statement_t *stmt;
00245 
00246     STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
00247     {
00248         var_t *func = stmt->u.var;
00249 
00250         write_function_stub( iface, func, *proc_offset );
00251 
00252         /* update proc_offset */
00253         func->procstring_offset = *proc_offset;
00254         *proc_offset += get_size_procformatstring_func( iface, func );
00255     }
00256 }
00257 
00258 
00259 static void write_dispatchtable(type_t *iface)
00260 {
00261     unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
00262     unsigned int method_count = 0;
00263     const statement_t *stmt;
00264 
00265     print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name);
00266     print_server("{\n");
00267     indent++;
00268 
00269     STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
00270     {
00271         var_t *func = stmt->u.var;
00272         if (is_interpreted_func( iface, func ))
00273             print_server("%s,\n", get_stub_mode() == MODE_Oif ? "NdrServerCall2" : "NdrServerCall");
00274         else
00275             print_server("%s_%s,\n", iface->name, get_name(func));
00276         method_count++;
00277     }
00278     print_server("0\n");
00279     indent--;
00280     print_server("};\n");
00281     print_server("static RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable =\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver));
00282     print_server("{\n");
00283     indent++;
00284     print_server("%u,\n", method_count);
00285     print_server("%s_table\n", iface->name);
00286     indent--;
00287     print_server("};\n");
00288     fprintf(server, "\n");
00289 }
00290 
00291 
00292 static void write_routinetable(type_t *iface)
00293 {
00294     const statement_t *stmt;
00295 
00296     print_server( "static const SERVER_ROUTINE %s_ServerRoutineTable[] =\n", iface->name );
00297     print_server( "{\n" );
00298     indent++;
00299     STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
00300     {
00301         var_t *func = stmt->u.var;
00302         if (is_local( func->attrs )) continue;
00303         print_server( "(SERVER_ROUTINE)%s%s,\n", prefix_server, get_name(func));
00304     }
00305     indent--;
00306     print_server( "};\n\n" );
00307 }
00308 
00309 
00310 static void write_rundown_routines(void)
00311 {
00312     context_handle_t *ch;
00313     int count = list_count( &context_handle_list );
00314 
00315     if (!count) return;
00316     print_server( "static const NDR_RUNDOWN RundownRoutines[] =\n" );
00317     print_server( "{\n" );
00318     indent++;
00319     LIST_FOR_EACH_ENTRY( ch, &context_handle_list, context_handle_t, entry )
00320     {
00321         print_server( "%s_rundown", ch->name );
00322         if (--count) fputc( ',', server );
00323         fputc( '\n', server );
00324     }
00325     indent--;
00326     print_server( "};\n\n" );
00327 }
00328 
00329 
00330 static void write_serverinfo(type_t *iface)
00331 {
00332     print_server( "static const MIDL_SERVER_INFO %s_ServerInfo =\n", iface->name );
00333     print_server( "{\n" );
00334     indent++;
00335     print_server( "&%s_StubDesc,\n", iface->name );
00336     print_server( "%s_ServerRoutineTable,\n", iface->name );
00337     print_server( "__MIDL_ProcFormatString.Format,\n" );
00338     print_server( "%s_FormatStringOffsetTable,\n", iface->name );
00339     print_server( "0,\n" );
00340     print_server( "0,\n" );
00341     print_server( "0,\n" );
00342     print_server( "0\n" );
00343     indent--;
00344     print_server( "};\n\n" );
00345 }
00346 
00347 
00348 static void write_stubdescdecl(type_t *iface)
00349 {
00350     print_server("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name);
00351     fprintf(server, "\n");
00352 }
00353 
00354 
00355 static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
00356 {
00357     print_server("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name);
00358     print_server("{\n");
00359     indent++;
00360     print_server("(void *)& %s___RpcServerInterface,\n", iface->name);
00361     print_server("MIDL_user_allocate,\n");
00362     print_server("MIDL_user_free,\n");
00363     print_server("{\n");
00364     indent++;
00365     print_server("0,\n");
00366     indent--;
00367     print_server("},\n");
00368     if (!list_empty( &context_handle_list ))
00369         print_server("RundownRoutines,\n");
00370     else
00371         print_server("0,\n");
00372     print_server("0,\n");
00373     if (expr_eval_routines)
00374         print_server("ExprEvalRoutines,\n");
00375     else
00376         print_server("0,\n");
00377     print_server("0,\n");
00378     print_server("__MIDL_TypeFormatString.Format,\n");
00379     print_server("1, /* -error bounds_check flag */\n");
00380     print_server("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
00381     print_server("0,\n");
00382     print_server("0x50100a4, /* MIDL Version 5.1.164 */\n");
00383     print_server("0,\n");
00384     print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
00385     print_server("0,  /* notify & notify_flag routine table */\n");
00386     print_server("1,  /* Flags */\n");
00387     print_server("0,  /* Reserved3 */\n");
00388     print_server("0,  /* Reserved4 */\n");
00389     print_server("0   /* Reserved5 */\n");
00390     indent--;
00391     print_server("};\n");
00392     fprintf(server, "\n");
00393 }
00394 
00395 
00396 static void write_serverinterfacedecl(type_t *iface)
00397 {
00398     unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
00399     UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
00400     const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT);
00401 
00402     if (endpoints) write_endpoints( server, iface->name, endpoints );
00403 
00404     print_server("static RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver));
00405     print_server( "static const MIDL_SERVER_INFO %s_ServerInfo;\n", iface->name );
00406     fprintf(server, "\n");
00407     print_server("static const RPC_SERVER_INTERFACE %s___RpcServerInterface =\n", iface->name );
00408     print_server("{\n");
00409     indent++;
00410     print_server("sizeof(RPC_SERVER_INTERFACE),\n");
00411     print_server("{{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",
00412                  uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
00413                  uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6],
00414                  uuid->Data4[7], MAJORVERSION(ver), MINORVERSION(ver));
00415     print_server("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */
00416     print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver));
00417     if (endpoints)
00418     {
00419         print_server("%u,\n", list_count(endpoints));
00420         print_server("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name);
00421     }
00422     else
00423     {
00424         print_server("0,\n");
00425         print_server("0,\n");
00426     }
00427     print_server("0,\n");
00428     print_server("&%s_ServerInfo,\n", iface->name);
00429     print_server("0,\n");
00430     indent--;
00431     print_server("};\n");
00432     if (old_names)
00433         print_server("RPC_IF_HANDLE %s_ServerIfHandle DECLSPEC_HIDDEN = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
00434                      iface->name, iface->name);
00435     else
00436         print_server("RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec DECLSPEC_HIDDEN = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
00437                      prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver), iface->name);
00438     fprintf(server, "\n");
00439 }
00440 
00441 
00442 static void init_server(void)
00443 {
00444     if (server)
00445         return;
00446     if (!(server = fopen(server_name, "w")))
00447         error("Could not open %s for output\n", server_name);
00448 
00449     print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
00450     print_server("#include <string.h>\n");
00451     fprintf(server, "\n");
00452     print_server("#include \"%s\"\n", header_name);
00453     print_server("\n");
00454     print_server( "#ifndef DECLSPEC_HIDDEN\n");
00455     print_server( "#define DECLSPEC_HIDDEN\n");
00456     print_server( "#endif\n");
00457     print_server( "\n");
00458 }
00459 
00460 
00461 static void write_server_stmts(const statement_list_t *stmts, int expr_eval_routines, unsigned int *proc_offset)
00462 {
00463     const statement_t *stmt;
00464     if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
00465     {
00466         if (stmt->type == STMT_LIBRARY)
00467             write_server_stmts(stmt->u.lib->stmts, expr_eval_routines, proc_offset);
00468         else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
00469         {
00470             type_t *iface = stmt->u.type;
00471             if (!need_stub(iface))
00472                 continue;
00473 
00474             fprintf(server, "/*****************************************************************************\n");
00475             fprintf(server, " * %s interface\n", iface->name);
00476             fprintf(server, " */\n");
00477             fprintf(server, "\n");
00478 
00479             if (statements_has_func(type_iface_get_stmts(iface)))
00480             {
00481                 write_serverinterfacedecl(iface);
00482                 write_stubdescdecl(iface);
00483 
00484                 write_function_stubs(iface, proc_offset);
00485 
00486                 print_server("#if !defined(__RPC_WIN%u__)\n", pointer_size == 8 ? 64 : 32);
00487                 print_server("#error  Invalid build platform for this stub.\n");
00488                 print_server("#endif\n");
00489 
00490                 fprintf(server, "\n");
00491                 write_procformatstring_offsets( server, iface );
00492                 write_stubdescriptor(iface, expr_eval_routines);
00493                 write_dispatchtable(iface);
00494                 write_routinetable(iface);
00495                 write_serverinfo(iface);
00496             }
00497         }
00498     }
00499 }
00500 
00501 static void write_server_routines(const statement_list_t *stmts)
00502 {
00503     unsigned int proc_offset = 0;
00504     int expr_eval_routines;
00505 
00506     if (need_inline_stubs_file( stmts ))
00507     {
00508         write_exceptions( server );
00509         print_server("\n");
00510         print_server("struct __server_frame\n");
00511         print_server("{\n");
00512         print_server("    __DECL_EXCEPTION_FRAME\n");
00513         print_server("    MIDL_STUB_MESSAGE _StubMsg;\n");
00514         print_server("};\n");
00515         print_server("\n");
00516         print_server("static int __server_filter( struct __server_frame *__frame )\n");
00517         print_server( "{\n");
00518         print_server( "    return (__frame->code == STATUS_ACCESS_VIOLATION) ||\n");
00519         print_server( "           (__frame->code == STATUS_DATATYPE_MISALIGNMENT) ||\n");
00520         print_server( "           (__frame->code == RPC_X_BAD_STUB_DATA) ||\n");
00521         print_server( "           (__frame->code == RPC_S_INVALID_BOUND);\n");
00522         print_server( "}\n");
00523         print_server( "\n");
00524     }
00525 
00526     write_formatstringsdecl(server, indent, stmts, need_stub);
00527     expr_eval_routines = write_expr_eval_routines(server, server_token);
00528     if (expr_eval_routines)
00529         write_expr_eval_routine_list(server, server_token);
00530     write_user_quad_list(server);
00531     write_rundown_routines();
00532 
00533     write_server_stmts(stmts, expr_eval_routines, &proc_offset);
00534 
00535     write_procformatstring(server, stmts, need_stub);
00536     write_typeformatstring(server, stmts, need_stub);
00537 }
00538 
00539 void write_server(const statement_list_t *stmts)
00540 {
00541     if (!do_server)
00542         return;
00543     if (do_everything && !need_stub_files(stmts))
00544         return;
00545 
00546     init_server();
00547     if (!server)
00548         return;
00549 
00550     if (do_win32 && do_win64)
00551     {
00552         fprintf(server, "#ifndef _WIN64\n\n");
00553         pointer_size = 4;
00554         write_server_routines( stmts );
00555         fprintf(server, "\n#else /* _WIN64 */\n\n");
00556         pointer_size = 8;
00557         write_server_routines( stmts );
00558         fprintf(server, "\n#endif /* _WIN64 */\n");
00559     }
00560     else if (do_win32)
00561     {
00562         pointer_size = 4;
00563         write_server_routines( stmts );
00564     }
00565     else if (do_win64)
00566     {
00567         pointer_size = 8;
00568         write_server_routines( stmts );
00569     }
00570 
00571     fclose(server);
00572 }

Generated on Sun May 27 2012 04:27:00 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.