rpcrt4/tests: Add a couple of tests for marshalling an array of strings. Take 2.

Dmitry Timoshkov dmitry at baikal.ru
Tue Mar 18 00:58:18 CDT 2014


I had to add broken() statements in order to avoid test failures under Windows
due to incorrect code generated by widl.

While investigating the problem I've found that both of the following
snippets in the idl file should lead to the same code generated by idl
compiler:

(1) typedef [string] char **str_array_t;
void get_names([out] int *n, [out, size_is(,*n)] str_array_t *names);

(2) typedef char **str_array_t;
void get_names([out] int *n, [out, string, size_is(,*n)] str_array_t *names);

widl accepts (1) but for (2) it errors out with
"write_string_tfs: Unimplemented for non-basic type names".
It seems that widl doesn't propagate [string] attribute from a typedef
properly otherwise it would generate that error in both cases.

I'd appreciate help in fixing widl to make these tests work, implementation
of EnumFolders and EnumTasks in the scheduler RPC interface depends on this.
rpcrt4 works correctly and the tests compiled with PSDK work under Wine.
---
 dlls/rpcrt4/tests/server.c   | 63 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/rpcrt4/tests/server.idl |  5 ++++
 2 files changed, 68 insertions(+)

diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index f32d3f7..e853c8f 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -54,6 +54,9 @@ static char *domain_and_user;
 /* type check statements generated in header file */
 fnprintf *p_printf = printf;
 
+static const WCHAR helloW[] = { 'H','e','l','l','o',0 };
+static const WCHAR worldW[] = { 'W','o','r','l','d','!',0 };
+
 static void InitFunctionPointers(void)
 {
     HMODULE hrpcrt4 = GetModuleHandleA("rpcrt4.dll");
@@ -572,6 +575,34 @@ void __cdecl s_get_name(name_t *name)
     name->name[name->size - 1] = 0;
 }
 
+void __cdecl s_get_names(int *n, str_array_t *names)
+{
+  str_array_t list;
+
+  list = MIDL_user_allocate(2 * sizeof(list[0]));
+  list[0] = MIDL_user_allocate(6);
+  strcpy(list[0], "Hello");
+  list[1] = MIDL_user_allocate(7);
+  strcpy(list[1], "World!");
+
+  *names = list;
+  *n = 2;
+}
+
+void __cdecl s_get_namesw(int *n, wstr_array_t *names)
+{
+  wstr_array_t list;
+
+  list = MIDL_user_allocate(2 * sizeof(list[0]));
+  list[0] = MIDL_user_allocate(sizeof(helloW));
+  lstrcpyW(list[0], helloW);
+  list[1] = MIDL_user_allocate(sizeof(worldW));
+  lstrcpyW(list[1], worldW);
+
+  *names = list;
+  *n = 2;
+}
+
 int __cdecl s_sum_pcarr2(int n, int **pa)
 {
   return s_sum_conf_array(*pa, n);
@@ -1191,12 +1222,44 @@ pointer_tests(void)
 
   if (!old_windows_version)
   {
+      int n;
+      str_array_t names;
+      wstr_array_t namesw;
+
       name.size = 10;
       name.name = buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, name.size);
       get_name(&name);
       ok(name.name == buffer, "[in,out] pointer should have stayed as %p but instead changed to %p\n", name.name, buffer);
       ok(!strcmp(name.name, "Jeremy Wh"), "name didn't unmarshall properly, expected \"Jeremy Wh\", but got \"%s\"\n", name.name);
       HeapFree(GetProcessHeap(), 0, name.name);
+
+      n = -1;
+      names = NULL;
+      get_names(&n, &names);
+      ok(n == 2, "expected 2, got %d\n", n);
+      /* FIXME: remove broken() once widl is fixed */
+todo_wine
+      ok(!strcmp(names[0], "Hello") || broken(strcmp(names[0], "Hello")), "expected Hello, got %s\n", names[0]);
+      /* FIXME: remove broken() once widl is fixed */
+todo_wine
+      ok(!strcmp(names[1], "World!") || broken(strcmp(names[1], "World!")), "expected World!, got %s\n", names[1]);
+      MIDL_user_free(names[0]);
+      MIDL_user_free(names[1]);
+      MIDL_user_free(names);
+
+      n = -1;
+      namesw = NULL;
+      get_namesw(&n, &namesw);
+      ok(n == 2, "expected 2, got %d\n", n);
+      /* FIXME: remove broken() once widl is fixed */
+todo_wine
+      ok(!lstrcmpW(namesw[0], helloW) || broken(lstrcmpW(namesw[0], helloW)), "expected Hello, got %s\n", wine_dbgstr_w(namesw[0]));
+      /* FIXME: remove broken() once widl is fixed */
+todo_wine
+      ok(!lstrcmpW(namesw[1], worldW) || broken(lstrcmpW(namesw[1], worldW)), "expected World!, got %s\n", wine_dbgstr_w(namesw[1]));
+      MIDL_user_free(namesw[0]);
+      MIDL_user_free(namesw[1]);
+      MIDL_user_free(namesw);
   }
 
   pa2 = a;
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index c193bae..a6458cd 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -328,6 +328,11 @@ cpp_quote("#endif")
   } name_t;
   void get_name([in,out] name_t *name);
 
+  typedef [string] char **str_array_t;
+  void get_names([out] int *n, [out, size_is(,*n)] str_array_t *names);
+  typedef [string] WCHAR **wstr_array_t;
+  void get_namesw([out] int *n, [out, size_is(,*n)] wstr_array_t *names);
+
   int sum_pcarr2(int n, [size_is(, n)] int **pa);
   int sum_L1_norms(int n, [size_is(n)] vector_t *vs);
 
-- 
1.8.5.5




More information about the wine-patches mailing list