widl [1/2]: Fix top-level conformant arrays with pointer attributes

Dan Hipschman dsh at linux.ucla.edu
Wed Sep 26 13:32:08 CDT 2007


This patch is part of the larger patch that isn't ready for commit yet, here:
http://winehq.org/pipermail/wine-patches/2007-September/044364.html

It only fixes some problems with top-level conformant arrays that have pointer
attributes on them.  This problem was reported by Mikolaj, and it seems is
needed for services.exe.  Included tests pass on wine and windows.  No new
existing tests fail, including everything in ole32.

---
 dlls/rpcrt4/tests/server.c   |   17 +++++++++++++++++
 dlls/rpcrt4/tests/server.idl |    2 ++
 tools/widl/typegen.c         |   24 +++++++++++++++++++-----
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index cdec58b..a7d6c21 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -199,6 +199,18 @@ s_sum_conf_array(int x[], int n)
 }
 
 int
+s_sum_unique_conf_array(int x[], int n)
+{
+  return s_sum_conf_array(x, n);
+}
+
+int
+s_sum_unique_conf_ptr(int *x, int n)
+{
+  return x ? s_sum_conf_array(x, n) : 0;
+}
+
+int
 s_sum_var_array(int x[20], int n)
 {
   ok(0 <= n, "RPC sum_var_array\n");
@@ -699,6 +711,7 @@ array_tests(void)
   cpsc_t cpsc;
   cs_t *cs;
   int n;
+  int ca[5] = {1, -2, 3, -4, 5};
 
   ok(cstr_length(str1, sizeof str1) == strlen(str1), "RPC cstr_length\n");
 
@@ -709,6 +722,10 @@ array_tests(void)
   ok(sum_conf_array(&c[7], 1) == 7, "RPC sum_conf_array\n");
   ok(sum_conf_array(&c[2], 0) == 0, "RPC sum_conf_array\n");
 
+  ok(sum_unique_conf_array(ca, 4) == -2, "RPC sum_unique_conf_array\n");
+  ok(sum_unique_conf_ptr(ca, 5) == 3, "RPC sum_unique_conf_array\n");
+  ok(sum_unique_conf_ptr(NULL, 10) == 0, "RPC sum_unique_conf_array\n");
+
   ok(sum_var_array(c, 10) == 45, "RPC sum_conf_array\n");
   ok(sum_var_array(&c[5], 2) == 11, "RPC sum_conf_array\n");
   ok(sum_var_array(&c[7], 1) == 7, "RPC sum_conf_array\n");
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index cadd1df..7a80489 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -111,6 +111,8 @@ interface IServer
   int test_list_length(test_list_t *ls);
   int sum_fixed_int_3d(int m[2][3][4]);
   int sum_conf_array([size_is(n)] int x[], int n);
+  int sum_unique_conf_array([size_is(n), unique] int x[], int n);
+  int sum_unique_conf_ptr([size_is(n), unique] int *x, int n);
   int sum_var_array([length_is(n)] int x[20], int n);
   int dot_two_vectors(vector_t vs[2]);
 
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 06ebd4f..419dbf7 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -1954,7 +1954,23 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
         return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset);
 
     if (is_array(type))
-        return write_array_tfs(file, var->attrs, type, var->name, typeformat_offset);
+    {
+        size_t off;
+        off = write_array_tfs(file, var->attrs, type, var->name, typeformat_offset);
+        if (pointer_type != RPC_FC_RP)
+        {
+            unsigned int absoff = type->typestring_offset;
+            short reloff = absoff - (*typeformat_offset + 2);
+            off = *typeformat_offset;
+            print_file(file, 0, "/* %d */\n", off);
+            print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", pointer_type,
+                       string_of_type(pointer_type));
+            print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
+                       reloff, reloff, absoff);
+            *typeformat_offset += 4;
+        }
+        return off;
+    }
 
     if (!is_ptr(type))
     {
@@ -2621,10 +2637,8 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
             }
             else if (phase != PHASE_FREE)
             {
-                if (pointer_type == RPC_FC_UP)
-                    print_phase_function(file, indent, "Pointer", phase, var, start_offset);
-                else
-                    print_phase_function(file, indent, array_type, phase, var, start_offset);
+                const char *t = pointer_type == RPC_FC_RP ? array_type : "Pointer";
+                print_phase_function(file, indent, t, phase, var, start_offset);
             }
         }
         else if (!is_ptr(var->type) && is_base_type(rtype))



More information about the wine-patches mailing list