Commit 59556de0 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

widl: Add support for generic binding handles.

parent 8a0cb2b5
...@@ -99,16 +99,21 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) ...@@ -99,16 +99,21 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{ {
const var_t *def = func->def; const var_t *def = func->def;
const var_t* explicit_handle_var; const var_t* explicit_handle_var;
const var_t* explicit_generic_handle_var = NULL;
const var_t* context_handle_var = NULL; const var_t* context_handle_var = NULL;
int has_full_pointer = is_full_pointer_function(func); int has_full_pointer = is_full_pointer_function(func);
/* check for a defined binding handle */ /* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func); explicit_handle_var = get_explicit_handle_var(func);
if (!explicit_handle_var) if (!explicit_handle_var)
context_handle_var = get_context_handle_var(func); {
explicit_generic_handle_var = get_explicit_generic_handle_var(func);
if (!explicit_generic_handle_var)
context_handle_var = get_context_handle_var(func);
}
if (explicit_handle) if (explicit_handle)
{ {
if (!explicit_handle_var || !context_handle_var) if (!explicit_handle_var || !explicit_generic_handle_var || !context_handle_var)
{ {
error("%s() does not define an explicit binding handle!\n", def->name); error("%s() does not define an explicit binding handle!\n", def->name);
return; return;
...@@ -148,7 +153,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) ...@@ -148,7 +153,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(client, " _RetVal;\n"); fprintf(client, " _RetVal;\n");
} }
if (implicit_handle || explicit_handle_var || context_handle_var) if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var)
print_client("RPC_BINDING_HANDLE _Handle = 0;\n"); print_client("RPC_BINDING_HANDLE _Handle = 0;\n");
print_client("RPC_MESSAGE _RpcMessage;\n"); print_client("RPC_MESSAGE _RpcMessage;\n");
...@@ -189,12 +194,20 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) ...@@ -189,12 +194,20 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("_Handle = %s;\n", explicit_handle_var->name); print_client("_Handle = %s;\n", explicit_handle_var->name);
fprintf(client, "\n"); fprintf(client, "\n");
} }
else if (explicit_generic_handle_var)
{
print_client("_Handle = %s_bind(%s);\n",
get_explicit_generic_handle_type(explicit_generic_handle_var)->name,
explicit_generic_handle_var->name);
fprintf(client, "\n");
}
else if (context_handle_var) else if (context_handle_var)
{ {
print_client("if (%s%s != 0)\n", is_ptr(context_handle_var->type) ? "*" : "", context_handle_var->name); print_client("if (%s%s != 0)\n", is_ptr(context_handle_var->type) ? "*" : "", context_handle_var->name);
indent++; indent++;
print_client("_Handle = NDRCContextBinding(%s%s);\n", is_ptr(context_handle_var->type) ? "*" : "", context_handle_var->name); print_client("_Handle = NDRCContextBinding(%s%s);\n", is_ptr(context_handle_var->type) ? "*" : "", context_handle_var->name);
indent--; indent--;
fprintf(client, "\n");
} }
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE); write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE);
...@@ -203,7 +216,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) ...@@ -203,7 +216,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent++; indent++;
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
print_client("_StubMsg.BufferLength,\n"); print_client("_StubMsg.BufferLength,\n");
if (implicit_handle || explicit_handle_var || context_handle_var) if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var)
print_client("_Handle);\n"); print_client("_Handle);\n");
else else
print_client("%s__MIDL_AutoBindHandle);\n", iface->name); print_client("%s__MIDL_AutoBindHandle);\n", iface->name);
...@@ -278,6 +291,17 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) ...@@ -278,6 +291,17 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n"); print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n");
if (!implicit_handle && explicit_generic_handle_var)
{
fprintf(client, "\n");
print_client("if (_Handle)\n");
indent++;
print_client("%s_unbind(%s, _Handle);\n",
get_explicit_generic_handle_type(explicit_generic_handle_var)->name,
explicit_generic_handle_var->name);
indent--;
}
indent--; indent--;
print_client("}\n"); print_client("}\n");
print_client("RpcEndFinally\n"); print_client("RpcEndFinally\n");
......
...@@ -34,9 +34,12 @@ ...@@ -34,9 +34,12 @@
#include "parser.h" #include "parser.h"
#include "header.h" #include "header.h"
typedef struct _user_type_t generic_handle_t;
static int indentation = 0; static int indentation = 0;
user_type_list_t user_type_list = LIST_INIT(user_type_list); user_type_list_t user_type_list = LIST_INIT(user_type_list);
static context_handle_list_t context_handle_list = LIST_INIT(context_handle_list); static context_handle_list_t context_handle_list = LIST_INIT(context_handle_list);
static struct list generic_handle_list = LIST_INIT(generic_handle_list);
static void indent(FILE *h, int delta) static void indent(FILE *h, int delta)
{ {
...@@ -343,7 +346,18 @@ static int context_handle_registered(const char *name) ...@@ -343,7 +346,18 @@ static int context_handle_registered(const char *name)
return 0; return 0;
} }
void check_for_user_types_and_context_handles(const var_list_t *list) static int generic_handle_registered(const char *name)
{
generic_handle_t *gh;
LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry)
if (!strcmp(name, gh->name))
return 1;
return 0;
}
/* check for types which require additional prototypes to be generated in the
* header */
void check_for_additional_prototype_types(const var_list_t *list)
{ {
const var_t *v; const var_t *v;
...@@ -365,6 +379,16 @@ void check_for_user_types_and_context_handles(const var_list_t *list) ...@@ -365,6 +379,16 @@ void check_for_user_types_and_context_handles(const var_list_t *list)
/* don't carry on parsing fields within this type */ /* don't carry on parsing fields within this type */
break; break;
} }
if (type->type != RPC_FC_BIND_PRIMITIVE && is_attr(type->attrs, ATTR_HANDLE)) {
if (!generic_handle_registered(name))
{
generic_handle_t *gh = xmalloc(sizeof(*gh));
gh->name = xstrdup(name);
list_add_tail(&generic_handle_list, &gh->entry);
}
/* don't carry on parsing fields within this type */
break;
}
if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
if (!user_type_registered(name)) if (!user_type_registered(name))
{ {
...@@ -378,7 +402,7 @@ void check_for_user_types_and_context_handles(const var_list_t *list) ...@@ -378,7 +402,7 @@ void check_for_user_types_and_context_handles(const var_list_t *list)
} }
else else
{ {
check_for_user_types_and_context_handles(type->fields); check_for_additional_prototype_types(type->fields);
} }
} }
} }
...@@ -407,6 +431,17 @@ void write_context_handle_rundowns(void) ...@@ -407,6 +431,17 @@ void write_context_handle_rundowns(void)
} }
} }
void write_generic_handle_routines(void)
{
generic_handle_t *gh;
LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry)
{
const char *name = gh->name;
fprintf(header, "handle_t __RPC_USER %s_bind(%s);\n", name, name);
fprintf(header, "void __RPC_USER %s_unbind(%s, handle_t);\n", name, name);
}
}
void write_typedef(type_t *type) void write_typedef(type_t *type)
{ {
fprintf(header, "typedef "); fprintf(header, "typedef ");
...@@ -537,6 +572,29 @@ const var_t* get_explicit_handle_var(const func_t* func) ...@@ -537,6 +572,29 @@ const var_t* get_explicit_handle_var(const func_t* func)
return NULL; return NULL;
} }
const type_t* get_explicit_generic_handle_type(const var_t* var)
{
const type_t *t;
for (t = var->type; is_ptr(t); t = t->ref)
if (t->type != RPC_FC_BIND_PRIMITIVE && is_attr(t->attrs, ATTR_HANDLE))
return t;
return NULL;
}
const var_t* get_explicit_generic_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 (get_explicit_generic_handle_type(var))
return var;
return NULL;
}
int has_out_arg_or_return(const func_t *func) int has_out_arg_or_return(const func_t *func)
{ {
const var_t *var; const var_t *var;
......
...@@ -62,7 +62,10 @@ extern void write_externdef(const var_t *v); ...@@ -62,7 +62,10 @@ extern void write_externdef(const var_t *v);
extern void write_library(const char *name, const attr_list_t *attr); extern void write_library(const char *name, const attr_list_t *attr);
extern void write_user_types(void); extern void write_user_types(void);
extern void write_context_handle_rundowns(void); extern void write_context_handle_rundowns(void);
extern void write_generic_handle_routines(void);
extern const var_t* get_explicit_handle_var(const func_t* func); extern const var_t* get_explicit_handle_var(const func_t* func);
extern const type_t* get_explicit_generic_handle_type(const var_t* var);
extern const var_t* get_explicit_generic_handle_var(const func_t* func);
extern int has_out_arg_or_return(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, extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
const UUID *uuid); const UUID *uuid);
......
...@@ -2072,7 +2072,7 @@ static void check_all_user_types(ifref_list_t *ifrefs) ...@@ -2072,7 +2072,7 @@ static void check_all_user_types(ifref_list_t *ifrefs)
{ {
const func_list_t *fs = ifref->iface->funcs; const func_list_t *fs = ifref->iface->funcs;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry)
check_for_user_types_and_context_handles(f->args); check_for_additional_prototype_types(f->args);
} }
} }
......
...@@ -601,6 +601,7 @@ int main(int argc,char *argv[]) ...@@ -601,6 +601,7 @@ int main(int argc,char *argv[])
fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
fprintf(header, "\n"); fprintf(header, "\n");
write_user_types(); write_user_types();
write_generic_handle_routines();
write_context_handle_rundowns(); write_context_handle_rundowns();
fprintf(header, "\n"); fprintf(header, "\n");
fprintf(header, "/* End additional prototypes */\n"); fprintf(header, "/* End additional prototypes */\n");
......
...@@ -312,7 +312,7 @@ struct _user_type_t { ...@@ -312,7 +312,7 @@ struct _user_type_t {
extern unsigned char pointer_default; extern unsigned char pointer_default;
extern user_type_list_t user_type_list; extern user_type_list_t user_type_list;
void check_for_user_types_and_context_handles(const var_list_t *list); void check_for_additional_prototype_types(const var_list_t *list);
void init_types(void); void init_types(void);
type_t *alloc_type(void); type_t *alloc_type(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment