[3/3] widl: Handle wire_marshal pointer attributes

Dan Hipschman dsh at linux.ucla.edu
Wed Jun 13 18:15:41 CDT 2007


This patch handles wire_marshal types where the wire type is a pointer.
The test is representative of the stuff seen in oaidl.idl, simplified.
Tests pass on wine and XP.

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

diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index 7b8e48a..aa5f3fc 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -238,6 +238,13 @@ s_dot_copy_vectors(vector_t u, vector_t v)
   return u.x * v.x + u.y * v.y + u.z * v.z;
 }
 
+int
+s_square_test_us(test_us_t *tus)
+{
+  int n = atoi(tus->us.x);
+  return n * n;
+}
+
 void
 s_stop(void)
 {
@@ -432,14 +439,47 @@ puint_t_UserFree(ULONG *flags, puint_t *p)
   HeapFree(GetProcessHeap(), 0, *p);
 }
 
+ULONG __RPC_USER
+us_t_UserSize(ULONG *flags, ULONG start, us_t *pus)
+{
+  return start + sizeof(struct wire_us);
+}
+
+unsigned char * __RPC_USER
+us_t_UserMarshal(ULONG *flags, unsigned char *buffer, us_t *pus)
+{
+  struct wire_us wus;
+  wus.x = atoi(pus->x);
+  memcpy(buffer, &wus, sizeof wus);
+  return buffer + sizeof wus;
+}
+
+unsigned char * __RPC_USER
+us_t_UserUnmarshal(ULONG *flags, unsigned char *buffer, us_t *pus)
+{
+  struct wire_us wus;
+  memcpy(&wus, buffer, sizeof wus);
+  pus->x = HeapAlloc(GetProcessHeap(), 0, 10);
+  sprintf(pus->x, "%d", wus.x);
+  return buffer + sizeof wus;
+}
+
+void __RPC_USER
+us_t_UserFree(ULONG *flags, us_t *pus)
+{
+  HeapFree(GetProcessHeap(), 0, pus->x);
+}
+
 static void
 pointer_tests(void)
 {
   static char p1[] = "11";
   test_list_t *list = make_list(make_list(make_list(null_list())));
+  static test_us_t tus = {{p1}};
 
   ok(test_list_length(list) == 3, "RPC test_list_length\n");
   ok(square_puint(p1) == 121, "RPC square_puint\n");
+  ok(square_test_us(&tus) == 121, "RPC square_test_us\n");
 
   free_list(list);
 }
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index 40ed67d..e3c3877 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -133,5 +133,22 @@ interface IServer
   typedef [wire_marshal(int)] void *puint_t;
   int square_puint(puint_t p);
   int dot_copy_vectors(vector_t u, vector_t v);
+
+  typedef struct wire_us *wire_us_t;
+  typedef [wire_marshal(wire_us_t)] struct us us_t;
+  struct us
+  {
+    void *x;
+  };
+  struct wire_us
+  {
+    int x;
+  };
+  typedef struct
+  {
+    us_t us;
+  } test_us_t;
+
+  int square_test_us(test_us_t *tus);
   void stop(void);
 }
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index de9ae54..0b115ab 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -828,7 +828,7 @@ static int processed(const type_t *type)
 
 static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
 {
-    unsigned int start, absoff;
+    unsigned int start, absoff, flags;
     unsigned int align = 0, ualign = 0;
     const char *name;
     type_t *utype = get_user_type(type, &name);
@@ -854,11 +854,19 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
         absoff = utype->typestring_offset;
     }
 
+    if (utype->type == RPC_FC_RP)
+        flags = 0x40;
+    else if (utype->type == RPC_FC_UP)
+        flags = 0x80;
+    else
+        flags = 0;
+
     start = *tfsoff;
     update_tfsoff(type, start, file);
     print_file(file, 0, "/* %d */\n", start);
     print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", RPC_FC_USER_MARSHAL);
-    print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
+    print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
+               flags | (align - 1), align - 1, flags);
     print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff);
     print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", usize, usize);
     print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", size, size);



More information about the wine-patches mailing list