Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenserver.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
1.7.6.1
|