diff --git a/tools/widl/client.c b/tools/widl/client.c index 773b31894e2..24bcda83749 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -124,6 +124,7 @@ static void write_function_stubs(type_t *iface) { func_t *func = iface->funcs; char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); var_t *var; int method_count = 0; unsigned int proc_offset = 0; @@ -132,6 +133,26 @@ static void write_function_stubs(type_t *iface) while (func) { var_t *def = func->def; + var_t* explicit_handle_var; + + /* check for a defined binding handle */ + explicit_handle_var = get_explicit_handle_var(func); + if (explicit_handle) + { + if (!explicit_handle_var) + { + error("%s() does not define an explicit binding handle!\n", def->name); + return; + } + } + else if (implicit_handle) + { + if (explicit_handle_var) + { + error("%s() must not define a binding handle!\n", def->name); + return; + } + } write_type(client, def->type, def, def->tname); fprintf(client, " "); @@ -157,7 +178,7 @@ static void write_function_stubs(type_t *iface) fprintf(client, " _RetVal;\n"); } - if (implicit_handle) + if (implicit_handle || explicit_handle_var) print_client("RPC_BINDING_HANDLE _Handle = 0;\n"); print_client("RPC_MESSAGE _RpcMessage;\n"); @@ -181,6 +202,11 @@ static void write_function_stubs(type_t *iface) print_client("_Handle = %s;\n", implicit_handle); fprintf(client, "\n"); } + else if (explicit_handle_var) + { + print_client("_Handle = %s;\n", explicit_handle_var->name); + fprintf(client, "\n"); + } /* emit the message buffer size */ print_client("_StubMsg.BufferLength ="); @@ -191,7 +217,7 @@ static void write_function_stubs(type_t *iface) indent++; print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); print_client("_StubMsg.BufferLength,\n"); - if (implicit_handle) + if (implicit_handle || explicit_handle_var) print_client("_Handle);\n"); else print_client("%s__MIDL_AutoBindHandle);\n", iface->name); diff --git a/tools/widl/header.c b/tools/widl/header.c index 070657a90bd..f68844b7f04 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -502,6 +502,28 @@ void write_library(const char *name, attr_t *attr) { fprintf(header, "\n"); } + +var_t* get_explicit_handle_var(func_t* func) +{ + var_t* var; + + if (!func->args) + return NULL; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + if (var->type->type == RPC_FC_IGNORE) + return var; + + var = PREV_LINK(var); + } + + return NULL; +} + + /********** INTERFACES **********/ int is_object(attr_t *a) @@ -739,10 +761,29 @@ static void write_method_proto(type_t *iface) static void write_function_proto(type_t *iface) { + char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); + var_t* explicit_handle_var; + func_t *cur = iface->funcs; while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); while (cur) { var_t *def = cur->def; + + /* check for a defined binding handle */ + explicit_handle_var = get_explicit_handle_var(cur); + if (explicit_handle) { + if (!explicit_handle_var) { + error("%s() does not define an explicit binding handle!\n", def->name); + return; + } + } else if (implicit_handle) { + if (explicit_handle_var) { + error("%s() must not define a binding handle!\n", def->name); + return; + } + } + /* FIXME: do we need to handle call_as? */ write_type(header, def->type, def, def->tname); fprintf(header, " "); diff --git a/tools/widl/header.h b/tools/widl/header.h index 5ecb8aa0ea3..c649513115c 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -42,5 +42,6 @@ extern void write_constdef(var_t *v); extern void write_externdef(var_t *v); extern void write_library(const char *name, attr_t *attr); extern void write_user_types(void); +extern var_t* get_explicit_handle_var(func_t* func); #endif diff --git a/tools/widl/server.c b/tools/widl/server.c index 2abfe837cbf..4c9fcbd6f4c 100644 --- a/tools/widl/server.c +++ b/tools/widl/server.c @@ -89,8 +89,11 @@ static void write_parameters_init(func_t *func) static void write_function_stubs(type_t *iface) { + char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); func_t *func = iface->funcs; var_t *var; + var_t* explicit_handle_var; unsigned int proc_offset = 0; while (NEXT_LINK(func)) func = NEXT_LINK(func); @@ -98,6 +101,25 @@ static void write_function_stubs(type_t *iface) { var_t *def = func->def; + /* check for a defined binding handle */ + explicit_handle_var = get_explicit_handle_var(func); + if (explicit_handle) + { + if (!explicit_handle_var) + { + error("%s() does not define an explicit binding handle!\n", def->name); + return; + } + } + else if (implicit_handle) + { + if (explicit_handle_var) + { + error("%s() must not define a binding handle!\n", def->name); + return; + } + } + write_type(server, def->type, def, def->tname); fprintf(server, " __RPC_STUB\n"); fprintf(server, "%s_", iface->name); @@ -152,6 +174,12 @@ static void write_function_stubs(type_t *iface) write_parameters_init(func); + if (explicit_handle_var) + { + print_server("%s = _pRpcMessage->Handle;\n", explicit_handle_var->name); + fprintf(server, "\n"); + } + print_server("RpcTryFinally\n"); print_server("{\n"); indent++;