This patch implements support for explicit user handles.
Regards Eric Kohl
ChangeLog: Implement support for explicit user handles.
diff --git a/tools/widl/client.c b/tools/widl/client.c index 86ead20..6a84e94 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -89,12 +89,14 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) { const var_t *def = func->def; const var_t* explicit_handle_var; + const var_t* explicit_user_handle_var;
/* check for a defined binding handle */ explicit_handle_var = get_explicit_handle_var(func); + explicit_user_handle_var = get_explicit_user_handle_var(func); if (explicit_handle) { - if (!explicit_handle_var) + if (!explicit_handle_var && !explicit_user_handle_var) { error("%s() does not define an explicit binding handle!\n", def->name); return; @@ -102,7 +104,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) } else if (implicit_handle) { - if (explicit_handle_var) + if (explicit_handle_var || explicit_user_handle_var) { error("%s() must not define a binding handle!\n", def->name); return; @@ -167,6 +169,19 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) print_client("_Handle = %s;\n", explicit_handle_var->name); fprintf(client, "\n"); } + else if (explicit_user_handle_var) + { + print_client("_Handle = %s_bind(%s);\n", + explicit_user_handle_var->type->name, + explicit_user_handle_var->name); + print_client("if (_Handle == 0)\n"); + print_client("{\n"); + indent++; + print_client("RpcRaiseException(RPC_S_INVALID_BINDING);\n"); + indent--; + print_client("}\n"); + fprintf(client, "\n"); + }
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE);
@@ -240,6 +255,19 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n");
+ if (explicit_user_handle_var) + { + fprintf(client, "\n"); + print_client("if (_Handle)\n"); + print_client("{\n"); + indent++; + print_client("%s_unbind(%s, _Handle);\n", + explicit_user_handle_var->type->name, + explicit_user_handle_var->name); + indent--; + print_client("}\n"); + } + indent--; print_client("}\n"); print_client("RpcEndFinally\n"); diff --git a/tools/widl/header.c b/tools/widl/header.c index 6f2da32..1119542 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -463,6 +463,21 @@ const var_t* get_explicit_handle_var(const func_t* func) return NULL; }
+const var_t* get_explicit_user_handle_var(const func_t* func) +{ + const var_t* var; + + if (!func->args) + return NULL; + + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + if ((var->type->type != RPC_FC_BIND_PRIMITIVE) && + is_attr(var->type->attrs, ATTR_HANDLE)) + return var; + + return NULL; +} + int has_out_arg_or_return(const func_t *func) { const var_t *var; @@ -480,6 +495,40 @@ int has_out_arg_or_return(const func_t *func) return 0; }
+static struct list user_handle_list = LIST_INIT(user_handle_list); + +struct user_handle +{ + struct list entry; + char name[1]; +}; + +void add_user_handle(type_t *type) +{ + struct user_handle *uh; + + if (is_attr(type->attrs, ATTR_HANDLE)) + { + uh = (struct user_handle *)xmalloc(sizeof(struct user_handle) + strlen(type->name)); + if (uh) + { + strcpy(uh->name, type->name); + list_add_tail(&user_handle_list, &uh->entry); + } + } +} + +void write_user_handles(void) +{ + const struct user_handle *uh; + + LIST_FOR_EACH_ENTRY(uh, &user_handle_list, struct user_handle, entry) + { + fprintf(header, "handle_t __RPC_USER %s_bind(%s);\n", uh->name, uh->name); + fprintf(header, "void __RPC_USER %s_unbind(%s, handle_t);\n", uh->name, uh->name); + } +} +
/********** INTERFACES **********/
@@ -710,6 +759,7 @@ static void write_function_protos(const type_t *iface) const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); const var_t* explicit_handle_var; + const var_t* explicit_user_handle_var; const func_t *cur; int prefixes_differ = strcmp(prefix_client, prefix_server);
@@ -720,13 +770,19 @@ static void write_function_protos(const type_t *iface)
/* check for a defined binding handle */ explicit_handle_var = get_explicit_handle_var(cur); - if (explicit_handle) { - if (!explicit_handle_var) { + explicit_user_handle_var = get_explicit_user_handle_var(cur); + if (explicit_handle) + { + if (!explicit_handle_var && !explicit_user_handle_var) + { error("%s() does not define an explicit binding handle!\n", def->name); return; } - } else if (implicit_handle) { - if (explicit_handle_var) { + } + else if (implicit_handle) + { + if (explicit_handle_var || explicit_user_handle_var) + { error("%s() must not define a binding handle!\n", def->name); return; } diff --git a/tools/widl/header.h b/tools/widl/header.h index 54655a2..7a6508b 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -53,9 +53,12 @@ extern void write_externdef(const var_t *v); extern void write_library(const char *name, const attr_list_t *attr); extern void write_user_types(void); extern const var_t* get_explicit_handle_var(const func_t* func); +extern const var_t* get_explicit_user_handle_var(const func_t* func); extern int has_out_arg_or_return(const func_t *func); extern void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid); +extern void add_user_handle(type_t *type); +extern void write_user_handles(void);
static inline int last_ptr(const type_t *type) { diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 4933c43..a6df42d 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1932,7 +1932,10 @@ static void process_typedefs(pident_list_t *pidents) type_t *type = find_type(var->name, 0);
if (! parse_only && do_header) + { write_typedef(type); + add_user_handle(type); + } if (in_typelib && type->attrs) add_typelib_entry(type);
diff --git a/tools/widl/server.c b/tools/widl/server.c index fd94c9a..2e261e5 100644 --- a/tools/widl/server.c +++ b/tools/widl/server.c @@ -61,6 +61,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) const func_t *func; const var_t *var; const var_t* explicit_handle_var; + const var_t* explicit_user_handle_var;
if (!iface->funcs) return; LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) @@ -69,9 +70,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
/* check for a defined binding handle */ explicit_handle_var = get_explicit_handle_var(func); + explicit_user_handle_var = get_explicit_user_handle_var(func); if (explicit_handle) { - if (!explicit_handle_var) + if (!explicit_handle_var && !explicit_user_handle_var) { error("%s() does not define an explicit binding handle!\n", def->name); return; @@ -79,7 +81,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) } else if (implicit_handle) { - if (explicit_handle_var) + if (explicit_handle_var || explicit_user_handle_var) { error("%s() must not define a binding handle!\n", def->name); return; diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 21657b6..0af449d 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -409,6 +409,7 @@ int main(int argc,char *argv[]) if(do_header) { fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); fprintf(header, "\n"); + write_user_handles(); write_user_types(); fprintf(header, "\n"); fprintf(header, "/* End additional prototypes */\n");