Rob Shearman : widl: Generate client and server code for using context handles.

Alexandre Julliard julliard at winehq.org
Fri Sep 28 06:45:56 CDT 2007


Module: wine
Branch: master
Commit: 2055e636aecbb0c54c5febd4510af9471903eda2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2055e636aecbb0c54c5febd4510af9471903eda2

Author: Rob Shearman <rob at codeweavers.com>
Date:   Thu Sep 27 17:38:27 2007 -0700

widl: Generate client and server code for using context handles.

---

 tools/widl/header.h  |    9 +++
 tools/widl/server.c  |   17 +++++--
 tools/widl/typegen.c |  140 +++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 143 insertions(+), 23 deletions(-)

diff --git a/tools/widl/header.h b/tools/widl/header.h
index 19a90a3..3c6a124 100644
--- a/tools/widl/header.h
+++ b/tools/widl/header.h
@@ -73,4 +73,13 @@ static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
     return is_attr(attrs, ATTR_STRING) && (last_ptr(type) || last_array(type));
 }
 
+static inline int is_context_handle(const type_t *type)
+{
+    const type_t *t;
+    for (t = type; is_ptr(t); t = t->ref)
+        if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+            return 1;
+    return 0;
+}
+
 #endif
diff --git a/tools/widl/server.c b/tools/widl/server.c
index fd94c9a..f708d25 100644
--- a/tools/widl/server.c
+++ b/tools/widl/server.c
@@ -184,10 +184,19 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
                     first_arg = 0;
                 else
                     fprintf(server, ",\n");
-                print_server("");
-                if (var->type->declarray)
-                    fprintf(server, "*");
-                write_name(server, var);
+                if (is_context_handle(var->type))
+                {
+                    print_server("(");
+                    write_type_left(server, var->type);
+                    fprintf(server, ")%sNDRSContextValue(%s)", is_ptr(var->type) ? "" : "*", var->name);
+                }
+                else
+                {
+                    print_server("");
+                    if (var->type->declarray)
+                        fprintf(server, "*");
+                    write_name(server, var);
+                }
             }
             fprintf(server, ");\n");
             indent--;
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index c2e16e5..88bb7c9 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -216,6 +216,16 @@ static int is_embedded_complex(const type_t *type)
         || (is_ptr(type) && type->ref->type == RPC_FC_IP);
 }
 
+static const char *get_context_handle_type_name(const type_t *type)
+{
+    const type_t *t;
+    for (t = type; is_ptr(t); t = t->ref)
+        if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+            return t->name;
+    assert(0);
+    return NULL;
+}
+
 static int compare_expr(const expr_t *a, const expr_t *b)
 {
     int ret;
@@ -1933,6 +1943,50 @@ static size_t write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
     return start_offset;
 }
 
+static size_t write_contexthandle_tfs(FILE *file, const type_t *type,
+                                      const var_t *var,
+                                      unsigned int *typeformat_offset)
+{
+    size_t start_offset = *typeformat_offset;
+    unsigned char flags = 0x08 /* strict */;
+
+    if (is_ptr(type))
+    {
+        flags |= 0x80;
+        if (type->type != RPC_FC_RP)
+            flags |= 0x01;
+    }
+    if (is_attr(var->attrs, ATTR_IN))
+        flags |= 0x40;
+    if (is_attr(var->attrs, ATTR_OUT))
+        flags |= 0x20;
+
+    WRITE_FCTYPE(file, FC_BIND_CONTEXT, *typeformat_offset);
+    print_file(file, 2, "0x%x,\t/* Context flags: ", flags);
+    if (((flags & 0x21) != 0x21) && (flags & 0x01))
+        print_file(file, 0, "can't be null, ");
+    if (flags & 0x02)
+        print_file(file, 0, "serialize, ");
+    if (flags & 0x04)
+        print_file(file, 0, "no serialize, ");
+    if (flags & 0x08)
+        print_file(file, 0, "strict, ");
+    if ((flags & 0x21) == 0x20)
+        print_file(file, 0, "out, ");
+    if ((flags & 0x21) == 0x21)
+        print_file(file, 0, "return, ");
+    if (flags & 0x40)
+        print_file(file, 0, "in, ");
+    if (flags & 0x80)
+        print_file(file, 0, "via ptr, ");
+    print_file(file, 0, "*/\n");
+    print_file(file, 2, "0, /* FIXME: rundown routine index*/\n");
+    print_file(file, 2, "0, /* FIXME: param num */\n");
+    *typeformat_offset += 4;
+
+    return start_offset;
+}
+
 static int get_ptr_attr(const type_t *t, int def_type)
 {
     while (TRUE)
@@ -1953,6 +2007,9 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
     int pointer_type;
     size_t offset;
 
+    if (is_context_handle(type))
+        return write_contexthandle_tfs(file, type, var, typeformat_offset);
+
     if (is_user_type(type))
     {
         write_user_tfs(file, type, typeformat_offset);
@@ -2295,12 +2352,20 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
 {
     int in_attr = is_attr(var->attrs, ATTR_IN);
     int out_attr = is_attr(var->attrs, ATTR_OUT);
+    const type_t *t;
 
     if (!in_attr && !out_attr)
         in_attr = 1;
 
     *alignment = 0;
 
+    for (t = var->type; is_ptr(t); t = t->ref)
+        if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+        {
+            *alignment = 4;
+            return 20;
+        }
+
     if (pass == PASS_OUT)
     {
         if (out_attr && is_ptr(var->type))
@@ -2579,7 +2644,39 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
 
         rtype = type->type;
 
-        if (is_user_type(var->type))
+        if (is_context_handle(type))
+        {
+            if (phase == PHASE_MARSHAL)
+            {
+                if (pass == PASS_IN)
+                {
+                    print_file(file, indent, "NdrClientContextMarshall(\n");
+                    print_file(file, indent + 1, "&_StubMsg,\n");
+                    print_file(file, indent + 1, "(NDR_CCONTEXT)%s%s,\n", is_ptr(type) ? "*" : "", var->name);
+                    print_file(file, indent + 1, "%s);\n", in_attr && out_attr ? "1" : "0");
+                }
+                else
+                {
+                    print_file(file, indent, "NdrServerContextMarshall(\n");
+                    print_file(file, indent + 1, "&_StubMsg,\n");
+                    print_file(file, indent + 1, "(NDR_SCONTEXT)%s,\n", var->name);
+                    print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown);\n", get_context_handle_type_name(var->type));
+                }
+            }
+            else if (phase == PHASE_UNMARSHAL)
+            {
+                if (pass == PASS_OUT)
+                {
+                    print_file(file, indent, "NdrClientContextUnmarshall(\n");
+                    print_file(file, indent + 1, "&_StubMsg,\n");
+                    print_file(file, indent + 1, "(NDR_CCONTEXT *)%s,\n", var->name);
+                    print_file(file, indent + 1, "_Handle);\n");
+                }
+                else
+                    print_file(file, indent, "%s = NdrServerContextUnmarshall(&_StubMsg);\n", var->name);
+            }
+        }
+        else if (is_user_type(var->type))
         {
             print_phase_function(file, indent, "UserMarshal", phase, var, start_offset);
         }
@@ -2906,28 +3003,33 @@ void declare_stub_args( FILE *file, int indent, const func_t *func )
         if (!out_attr && !in_attr)
             in_attr = 1;
 
-        if (!in_attr && !var->type->size_is && !is_string)
+        if (is_context_handle(var->type))
+            print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
+        else
         {
+            if (!in_attr && !var->type->size_is && !is_string)
+            {
+                print_file(file, indent, "");
+                write_type(file, var->type->ref, FALSE, "_W%u", i++);
+                fprintf(file, ";\n");
+            }
+
             print_file(file, indent, "");
-            write_type(file, var->type->ref, FALSE, "_W%u", i++);
+            write_type_left(file, var->type);
+            fprintf(file, " ");
+            if (var->type->declarray) {
+                fprintf(file, "( *");
+                write_name(file, var);
+                fprintf(file, " )");
+            } else
+                write_name(file, var);
+            write_type_right(file, var->type, FALSE);
             fprintf(file, ";\n");
-        }
-
-        print_file(file, indent, "");
-        write_type_left(file, var->type);
-        fprintf(file, " ");
-        if (var->type->declarray) {
-            fprintf(file, "( *");
-            write_name(file, var);
-            fprintf(file, " )");
-        } else
-            write_name(file, var);
-        write_type_right(file, var->type, FALSE);
-        fprintf(file, ";\n");
 
-        if (decl_indirect(var->type))
-            print_file(file, indent, "void *_p_%s = &%s;\n",
-                       var->name, var->name);
+            if (decl_indirect(var->type))
+                print_file(file, indent, "void *_p_%s = &%s;\n",
+                           var->name, var->name);
+        }
     }
 }
 




More information about the wine-cvs mailing list