WIDL: Implement support for explicit user handles

Eric Kohl eric.kohl at t-online.de
Sun Jun 24 16:57:50 CDT 2007


This patch implements support for explicit user handles.


Regards
Eric Kohl


ChangeLog:
	Implement support for explicit user handles.



-------------- next part --------------
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");




More information about the wine-devel mailing list