widl [2/2]: Fix string codes in pointer descriptions

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


This patch fixes a problem with string types in structures.  It uses the
string format codes (e.g., RPC_FC_C_CSTRING) in the pointer descriptions
instead of the base type (e.g., RPC_FC_CHAR).  This was reported by
Mikolaj, and is needed for services.exe.

---
 dlls/rpcrt4/tests/server.c   |   20 +++++++++++++++++++-
 dlls/rpcrt4/tests/server.idl |   20 ++++++++++++++++++++
 tools/widl/typegen.c         |   26 ++++++++++++++++++++++++--
 3 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index a7d6c21..f4ba399 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -390,6 +390,18 @@ s_check_null(int *null)
   ok(!null, "RPC check_null\n");
 }
 
+int
+s_str_struct_len(str_struct_t *s)
+{
+  return lstrlenA(s->s);
+}
+
+int
+s_wstr_struct_len(wstr_struct_t *s)
+{
+  return lstrlenW(s->s);
+}
+
 void
 s_stop(void)
 {
@@ -428,7 +440,8 @@ run_client(const char *test)
 static void
 basic_tests(void)
 {
-  static char string[] = "I am a string";
+  char string[] = "I am a string";
+  WCHAR wstring[] = {'I',' ','a','m',' ','a',' ','w','s','t','r','i','n','g', 0};
   static int f[5] = {1, 3, 0, -2, -4};
   static vector_t a = {1, 3, 7};
   static vector_t vec1 = {4, -2, 1}, vec2 = {-5, 2, 3}, *pvec2 = &vec2;
@@ -448,6 +461,8 @@ basic_tests(void)
   short h;
   char c;
   int x;
+  str_struct_t ss = {string};
+  wstr_struct_t ws = {wstring};
 
   ok(int_return() == INT_CODE, "RPC int_return\n");
 
@@ -465,6 +480,9 @@ basic_tests(void)
   ok(str_length(string) == strlen(string), "RPC str_length\n");
   ok(dot_self(&a) == 59, "RPC dot_self\n");
 
+  ok(str_struct_len(&ss) == lstrlenA(string), "RPC str_struct_len\n");
+  ok(wstr_struct_len(&ws) == lstrlenW(wstring), "RPC str_struct_len\n");
+
   v = 0.0;
   u = square_half(3.0, &v);
   ok(u == 9.0, "RPC square_half\n");
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index 7a80489..d8a1ca3 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -33,6 +33,13 @@ typedef struct tag_vector
 ]
 interface IServer
 {
+cpp_quote("#if 0")
+  typedef wchar_t WCHAR;
+cpp_quote("#endif")
+
+  typedef [string] char *str_t;
+  typedef [string] WCHAR *wstr_t;
+
   typedef struct
   {
     int *pi;
@@ -228,5 +235,18 @@ interface IServer
   int sum_bogus(bogus_t *b);
   void check_null([unique] int *null);
 
+  typedef struct
+  {
+    str_t s;
+  } str_struct_t;
+
+  typedef struct
+  {
+    wstr_t s;
+  } wstr_struct_t;
+
+  int str_struct_len(str_struct_t *s);
+  int wstr_struct_len(wstr_struct_t *s);
+
   void stop(void);
 }
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 419dbf7..205529d 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -101,6 +101,10 @@ const char *string_of_type(unsigned char type)
     case RPC_FC_ALIGNM4: return "FC_ALIGNM4";
     case RPC_FC_ALIGNM8: return "FC_ALIGNM8";
     case RPC_FC_POINTER: return "FC_POINTER";
+    case RPC_FC_C_CSTRING: return "FC_C_CSTRING";
+    case RPC_FC_C_WSTRING: return "FC_C_WSTRING";
+    case RPC_FC_CSTRING: return "FC_CSTRING";
+    case RPC_FC_WSTRING: return "FC_WSTRING";
     default:
         error("string_of_type: unknown type 0x%02x\n", type);
         return NULL;
@@ -826,12 +830,30 @@ static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, size
     return 4;
 }
 
+static unsigned char conf_string_type_of_char_type(unsigned char t)
+{
+    switch (t)
+    {
+    case RPC_FC_BYTE:
+    case RPC_FC_CHAR:
+        return RPC_FC_C_CSTRING;
+    case RPC_FC_WCHAR:
+        return RPC_FC_C_WSTRING;
+    }
+
+    error("string_type_of_char_type: unrecognized type %d", t);
+    return 0;
+}
+
 static unsigned int write_simple_pointer(FILE *file, const type_t *type)
 {
+    unsigned char fc
+        = is_string_type(type->attrs, type)
+        ? conf_string_type_of_char_type(type->ref->type)
+        : type->ref->type;
     print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n",
                type->type, string_of_type(type->type));
-    print_file(file, 2, "0x%02x,\t/* %s */\n", type->ref->type,
-               string_of_type(type->ref->type));
+    print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
     print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
     return 4;
 }



More information about the wine-patches mailing list