Rob Shearman : widl: Fix marshalling/unmarshalling of enum arguments.

Alexandre Julliard julliard at winehq.org
Mon Feb 16 09:35:02 CST 2009


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

Author: Rob Shearman <robertshearman at gmail.com>
Date:   Sat Feb 14 18:10:53 2009 +0000

widl: Fix marshalling/unmarshalling of enum arguments.

The generated code should use NdrSimpleType{Marshall,Unmarshall} instead
of direct buffer access, since the memory size isn't always equal to
the size on the wire and extra checks.

---

 tools/widl/typegen.c |   43 ++++++++++++++++++++++++++++++++-----------
 1 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 89b7ccf..fd51dc5 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -3071,7 +3071,6 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
 {
     int in_attr, out_attr, pointer_type;
     const type_t *type = var->type;
-    unsigned char rtype;
     unsigned int start_offset = type->typestring_offset;
 
     pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
@@ -3097,7 +3096,6 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
         }
 
     write_parameter_conf_or_var_exprs(file, indent, local_var_prefix, phase, var);
-    rtype = get_struct_type(type);
 
     if (is_context_handle(type))
     {
@@ -3204,14 +3202,29 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
             }
         }
     }
-    else if (!is_ptr(var->type) && is_base_type(rtype))
+    else if (is_base_type(type->type))
     {
-        if (phase != PHASE_FREE)
-            print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
+        if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
+        {
+            if (type->type == RPC_FC_ENUM16 || type->type == RPC_FC_ENUM32)
+            {
+                if (phase == PHASE_MARSHAL)
+                    print_file(file, indent, "NdrSimpleTypeMarshall(\n");
+                else
+                    print_file(file, indent, "NdrSimpleTypeUnmarshall(\n");
+                print_file(file, indent+1, "&__frame->_StubMsg,\n");
+                print_file(file, indent+1, "(unsigned char *)&%s%s,\n",
+                           local_var_prefix,
+                           var->name);
+                print_file(file, indent+1, "0x%02x /* %s */);\n", type->type, string_of_type(type->type));
+            }
+            else
+                print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
+        }
     }
-    else if (!is_ptr(var->type))
+    else if (is_struct(type->type))
     {
-        switch (rtype)
+        switch (get_struct_type(type))
         {
         case RPC_FC_STRUCT:
         case RPC_FC_PSTRUCT:
@@ -3228,7 +3241,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
             print_phase_function(file, indent, "ComplexStruct", local_var_prefix, phase, var, start_offset);
             break;
         default:
-            error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, rtype);
+            error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, get_struct_type(type));
         }
     }
     else
@@ -3236,13 +3249,21 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
         const type_t *ref = type_pointer_get_ref(type);
         if (type->type == RPC_FC_RP && is_base_type(ref->type))
         {
-            if (phase != PHASE_FREE)
-                print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
+            /* base types have known sizes, so don't need a sizing pass
+             * and don't have any memory to free and so don't need a
+             * freeing pass */
+            if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
+            {
+                if (ref->type == RPC_FC_ENUM16 || ref->type == RPC_FC_ENUM32)
+                    print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
+                else
+                    print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
+            }
         }
         else if (type->type == RPC_FC_RP && get_struct_type(ref) == RPC_FC_STRUCT &&
                  !is_user_type(ref))
         {
-            if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE)
+            if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
                 print_phase_function(file, indent, "SimpleStruct",
                                      local_var_prefix, phase, var,
                                      ref->typestring_offset);




More information about the wine-cvs mailing list