1 /*
2  * Tests for WIDL and RPC server/clients.
3  *
4  * Copyright (C) Google 2007 (Dan Hipschman)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #define COBJMACROS
22 #include <windows.h>
23 #include <ole2.h>
24 #include <oleauto.h>
25 #include <secext.h>
26 #include <rpcdce.h>
27 #include <netfw.h>
28 #include "wine/test.h"
29 #include "server_s.h"
30 #include "server_defines.h"
31 
32 #include <stddef.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 
36 #define PORT "4114"
37 #define PIPE "\\pipe\\wine_rpcrt4_test"
38 
39 #define INT_CODE 4198
40 
41 static const char *progname;
42 static BOOL old_windows_version;
43 
44 static HANDLE stop_event, stop_wait_event;
45 
46 static void (WINAPI *pNDRSContextMarshall2)(RPC_BINDING_HANDLE, NDR_SCONTEXT, void*, NDR_RUNDOWN, void*, ULONG);
47 static NDR_SCONTEXT (WINAPI *pNDRSContextUnmarshall2)(RPC_BINDING_HANDLE, void*, ULONG, void*, ULONG);
48 static RPC_STATUS (WINAPI *pRpcServerRegisterIfEx)(RPC_IF_HANDLE,UUID*, RPC_MGR_EPV*, unsigned int,
49                    unsigned int,RPC_IF_CALLBACK_FN*);
50 static RPC_STATUS (WINAPI *pRpcBindingSetAuthInfoExA)(RPC_BINDING_HANDLE, RPC_CSTR, ULONG, ULONG,
51                                                       RPC_AUTH_IDENTITY_HANDLE, ULONG, RPC_SECURITY_QOS *);
52 static RPC_STATUS (WINAPI *pRpcServerRegisterAuthInfoA)(RPC_CSTR, ULONG, RPC_AUTH_KEY_RETRIEVAL_FN, LPVOID);
53 
54 static char *domain_and_user;
55 
56 /* type check statements generated in header file */
57 fnprintf *p_printf = printf;
58 
59 static const WCHAR helloW[] = { 'H','e','l','l','o',0 };
60 static const WCHAR worldW[] = { 'W','o','r','l','d','!',0 };
61 
62 static void InitFunctionPointers(void)
63 {
64     HMODULE hrpcrt4 = GetModuleHandleA("rpcrt4.dll");
65 
66     pNDRSContextMarshall2 = (void *)GetProcAddress(hrpcrt4, "NDRSContextMarshall2");
67     pNDRSContextUnmarshall2 = (void *)GetProcAddress(hrpcrt4, "NDRSContextUnmarshall2");
68     pRpcServerRegisterIfEx = (void *)GetProcAddress(hrpcrt4, "RpcServerRegisterIfEx");
69     pRpcBindingSetAuthInfoExA = (void *)GetProcAddress(hrpcrt4, "RpcBindingSetAuthInfoExA");
70     pRpcServerRegisterAuthInfoA = (void *)GetProcAddress(hrpcrt4, "RpcServerRegisterAuthInfoA");
71 
72     if (!pNDRSContextMarshall2) old_windows_version = TRUE;
73 }
74 
75 void __RPC_FAR *__RPC_USER
76 midl_user_allocate(SIZE_T n)
77 {
78   return HeapAlloc(GetProcessHeap(), 0, n);
79 }
80 
81 void __RPC_USER
82 midl_user_free(void __RPC_FAR *p)
83 {
84   HeapFree(GetProcessHeap(), 0, p);
85 }
86 
87 static char *
88 xstrdup(const char *s)
89 {
90   char *d = HeapAlloc(GetProcessHeap(), 0, strlen(s) + 1);
91   strcpy(d, s);
92   return d;
93 }
94 
95 int __cdecl s_int_return(void)
96 {
97   return INT_CODE;
98 }
99 
100 int __cdecl s_square(int x)
101 {
102   return x * x;
103 }
104 
105 int __cdecl s_sum(int x, int y)
106 {
107   return x + y;
108 }
109 
110 signed char __cdecl s_sum_char(signed char x, signed char y)
111 {
112     return x + y;
113 }
114 
115 short __cdecl s_sum_short(short x, short y)
116 {
117     return x + y;
118 }
119 
120 int __cdecl s_sum_float(float x, float y)
121 {
122     return x + y;
123 }
124 
125 int __cdecl s_sum_double_int(int x, double y)
126 {
127     return x + y;
128 }
129 
130 hyper __cdecl s_sum_hyper(hyper x, hyper y)
131 {
132     return x + y;
133 }
134 
135 int __cdecl s_sum_hyper_int(hyper x, hyper y)
136 {
137     return x + y;
138 }
139 
140 int __cdecl s_sum_char_hyper(signed char x, hyper y)
141 {
142     return x + y;
143 }
144 
145 void __cdecl s_square_out(int x, int *y)
146 {
147   *y = s_square(x);
148 }
149 
150 void __cdecl s_square_ref(int *x)
151 {
152   *x = s_square(*x);
153 }
154 
155 int __cdecl s_str_length(const char *s)
156 {
157   return strlen(s);
158 }
159 
160 int __cdecl s_str_t_length(str_t s)
161 {
162   return strlen(s);
163 }
164 
165 int __cdecl s_cstr_length(const char *s, int n)
166 {
167   int len = 0;
168   while (0 < n-- && *s++)
169     ++len;
170   return len;
171 }
172 
173 int __cdecl s_dot_self(vector_t *v)
174 {
175   return s_square(v->x) + s_square(v->y) + s_square(v->z);
176 }
177 
178 double __cdecl s_square_half(double x, double *y)
179 {
180   *y = x / 2.0;
181   return x * x;
182 }
183 
184 float __cdecl s_square_half_float(float x, float *y)
185 {
186   *y = x / 2.0f;
187   return x * x;
188 }
189 
190 LONG __cdecl s_square_half_long(LONG x, LONG *y)
191 {
192   *y = x / 2;
193   return x * x;
194 }
195 
196 int __cdecl s_sum_fixed_array(int a[5])
197 {
198   return a[0] + a[1] + a[2] + a[3] + a[4];
199 }
200 
201 int __cdecl s_pints_sum(pints_t *pints)
202 {
203   return *pints->pi + **pints->ppi + ***pints->pppi;
204 }
205 
206 double __cdecl s_ptypes_sum(ptypes_t *pt)
207 {
208   return *pt->pc + *pt->ps + *pt->pl + *pt->pf + *pt->pd;
209 }
210 
211 int __cdecl s_dot_pvectors(pvectors_t *p)
212 {
213   return p->pu->x * (*p->pv)->x + p->pu->y * (*p->pv)->y + p->pu->z * (*p->pv)->z;
214 }
215 
216 int __cdecl s_sum_sp(sp_t *sp)
217 {
218   return sp->x + sp->s->x;
219 }
220 
221 double __cdecl s_square_sun(sun_t *su)
222 {
223   switch (su->s)
224   {
225   case SUN_I: return su->u.i * su->u.i;
226   case SUN_F1:
227   case SUN_F2: return su->u.f * su->u.f;
228   case SUN_PI: return (*su->u.pi) * (*su->u.pi);
229   default:
230     return 0.0;
231   }
232 }
233 
234 int __cdecl s_test_list_length(test_list_t *list)
235 {
236   return (list->t == TL_LIST
237           ? 1 + s_test_list_length(list->u.tail)
238           : 0);
239 }
240 
241 int __cdecl s_sum_fixed_int_3d(int m[2][3][4])
242 {
243   int i, j, k;
244   int sum = 0;
245 
246   for (i = 0; i < 2; ++i)
247     for (j = 0; j < 3; ++j)
248       for (k = 0; k < 4; ++k)
249         sum += m[i][j][k];
250 
251   return sum;
252 }
253 
254 int __cdecl s_sum_conf_array(int x[], int n)
255 {
256   int *p = x, *end = p + n;
257   int sum = 0;
258 
259   while (p < end)
260     sum += *p++;
261 
262   return sum;
263 }
264 
265 int __cdecl s_sum_conf_ptr_by_conf_ptr(int n1, int *n2_then_x1, int *x2)
266 {
267   int i;
268   int sum = 0;
269   if(n1 == 0)
270     return 0;
271 
272   for(i = 1; i < n1; ++i)
273     sum += n2_then_x1[i];
274 
275   for(i = 0; i < *n2_then_x1; ++i)
276     sum += x2[i];
277 
278   return sum;
279 }
280 
281 int __cdecl s_sum_unique_conf_array(int x[], int n)
282 {
283   return s_sum_conf_array(x, n);
284 }
285 
286 int __cdecl s_sum_unique_conf_ptr(int *x, int n)
287 {
288   return x ? s_sum_conf_array(x, n) : 0;
289 }
290 
291 int __cdecl s_sum_var_array(int x[20], int n)
292 {
293   ok(0 <= n, "RPC sum_var_array\n");
294   ok(n <= 20, "RPC sum_var_array\n");
295 
296   return s_sum_conf_array(x, n);
297 }
298 
299 int __cdecl s_sum_complex_array(int n, refpint_t pi[])
300 {
301   int total = 0;
302   for (; n > 0; n--)
303     total += *pi[n - 1];
304   return total;
305 }
306 
307 int __cdecl s_dot_two_vectors(vector_t vs[2])
308 {
309   return vs[0].x * vs[1].x + vs[0].y * vs[1].y + vs[0].z * vs[1].z;
310 }
311 
312 void __cdecl s_get_number_array(int x[20], int *n)
313 {
314   int c[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
315   memcpy(x, c, sizeof(c));
316   *n = ARRAY_SIZE(c);
317 }
318 
319 int __cdecl s_sum_cs(cs_t *cs)
320 {
321   return s_sum_conf_array(cs->ca, cs->n);
322 }
323 
324 int __cdecl s_sum_cps(cps_t *cps)
325 {
326   int sum = 0;
327   int i;
328 
329   for (i = 0; i < *cps->pn; ++i)
330     sum += cps->ca1[i];
331 
332   for (i = 0; i < 2 * cps->n; ++i)
333     sum += cps->ca2[i];
334 
335   return sum;
336 }
337 
338 int __cdecl s_sum_cpsc(cpsc_t *cpsc)
339 {
340   int sum = 0;
341   int i;
342   for (i = 0; i < (cpsc->c ? cpsc->a : cpsc->b); ++i)
343     sum += cpsc->ca[i];
344   return sum;
345 }
346 
347 int __cdecl s_get_cpsc(int n, cpsc_t *cpsc)
348 {
349   int i, ret;
350 
351   cpsc->a = 2 * n;
352   cpsc->b = 2;
353   cpsc->c = 1;
354   cpsc->ca = MIDL_user_allocate( cpsc->a * sizeof(int) );
355   for (i = ret = 0; i < cpsc->a; i++) cpsc->ca[i] = i;
356   for (i = ret = 0; i < cpsc->a; i++) ret += cpsc->ca[i];
357   return ret;
358 }
359 
360 int __cdecl s_square_puint(puint_t p)
361 {
362   int n = atoi(p);
363   return n * n;
364 }
365 
366 int __cdecl s_sum_puints(puints_t *p)
367 {
368   int sum = 0;
369   int i;
370   for (i = 0; i < p->n; ++i)
371     sum += atoi(p->ps[i]);
372   return sum;
373 }
374 
375 int __cdecl s_sum_cpuints(cpuints_t *p)
376 {
377   int sum = 0;
378   int i;
379   for (i = 0; i < p->n; ++i)
380     sum += atoi(p->ps[i]);
381   return sum;
382 }
383 
384 int __cdecl s_dot_copy_vectors(vector_t u, vector_t v)
385 {
386   return u.x * v.x + u.y * v.y + u.z * v.z;
387 }
388 
389 int __cdecl s_square_test_us(test_us_t *tus)
390 {
391   int n = atoi(tus->us.x);
392   return n * n;
393 }
394 
395 double __cdecl s_square_encu(encu_t *eu)
396 {
397   switch (eu->t)
398   {
399   case ENCU_I: return eu->tagged_union.i * eu->tagged_union.i;
400   case ENCU_F: return eu->tagged_union.f * eu->tagged_union.f;
401   default:
402     return 0.0;
403   }
404 }
405 
406 double __cdecl s_square_unencu(int t, unencu_t *eu)
407 {
408   switch (t)
409   {
410   case ENCU_I: return eu->i * eu->i;
411   case ENCU_F: return eu->f * eu->f;
412   default:
413     return 0.0;
414   }
415 }
416 
417 void __cdecl s_check_se2(se_t *s)
418 {
419   ok(s->f == E2, "check_se2\n");
420 }
421 
422 int __cdecl s_sum_parr(int *a[3])
423 {
424   return s_sum_pcarr(a, 3);
425 }
426 
427 int __cdecl s_sum_pcarr(int *a[], int n)
428 {
429   int i, s = 0;
430   for (i = 0; i < n; ++i)
431     s += *a[i];
432   return s;
433 }
434 
435 int __cdecl s_enum_ord(e_t e)
436 {
437   switch (e)
438   {
439   case E1: return 1;
440   case E2: return 2;
441   case E3: return 3;
442   case E4: return 4;
443   default:
444     return 0;
445   }
446 }
447 
448 double __cdecl s_square_encue(encue_t *eue)
449 {
450   switch (eue->t)
451   {
452   case E1: return eue->tagged_union.i1 * eue->tagged_union.i1;
453   case E2: return eue->tagged_union.f2 * eue->tagged_union.f2;
454   default:
455     return 0.0;
456   }
457 }
458 
459 int __cdecl s_sum_toplev_conf_2n(int *x, int n)
460 {
461   int sum = 0;
462   int i;
463   for (i = 0; i < 2 * n; ++i)
464     sum += x[i];
465   return sum;
466 }
467 
468 int __cdecl s_sum_toplev_conf_cond(int *x, int a, int b, int c)
469 {
470   int sum = 0;
471   int n = c ? a : b;
472   int i;
473   for (i = 0; i < n; ++i)
474     sum += x[i];
475   return sum;
476 }
477 
478 double __cdecl s_sum_aligns(aligns_t *a)
479 {
480   return a->c + a->i + a->s + a->d;
481 }
482 
483 int __cdecl s_sum_padded(padded_t *p)
484 {
485   return p->i + p->c;
486 }
487 
488 int __cdecl s_sum_padded2(padded_t ps[2])
489 {
490   return s_sum_padded(&ps[0]) + s_sum_padded(&ps[1]);
491 }
492 
493 int __cdecl s_sum_padded_conf(padded_t *ps, int n)
494 {
495   int sum = 0;
496   int i;
497   for (i = 0; i < n; ++i)
498     sum += s_sum_padded(&ps[i]);
499   return sum;
500 }
501 
502 int __cdecl s_sum_bogus(bogus_t *b)
503 {
504   return *b->h.p1 + *b->p2 + *b->p3 + b->c;
505 }
506 
507 void __cdecl s_check_null(int *null)
508 {
509   ok(!null, "RPC check_null\n");
510 }
511 
512 int __cdecl s_str_struct_len(str_struct_t *s)
513 {
514   return lstrlenA(s->s);
515 }
516 
517 int __cdecl s_wstr_struct_len(wstr_struct_t *s)
518 {
519   return lstrlenW(s->s);
520 }
521 
522 int __cdecl s_sum_doub_carr(doub_carr_t *dc)
523 {
524   int i, j;
525   int sum = 0;
526   for (i = 0; i < dc->n; ++i)
527     for (j = 0; j < dc->a[i]->n; ++j)
528       sum += dc->a[i]->a[j];
529   return sum;
530 }
531 
532 void __cdecl s_make_pyramid_doub_carr(unsigned char n, doub_carr_t **dc)
533 {
534   doub_carr_t *t;
535   int i, j;
536   t = MIDL_user_allocate(FIELD_OFFSET(doub_carr_t, a[n]));
537   t->n = n;
538   for (i = 0; i < n; ++i)
539   {
540     int v = i + 1;
541     t->a[i] = MIDL_user_allocate(FIELD_OFFSET(doub_carr_1_t, a[v]));
542     t->a[i]->n = v;
543     for (j = 0; j < v; ++j)
544       t->a[i]->a[j] = j + 1;
545   }
546   *dc = t;
547 }
548 
549 unsigned __cdecl s_hash_bstr(bstr_t b)
550 {
551   short n = b[-1];
552   short *s = b;
553   unsigned hash = 0;
554   short i;
555   for (i = 0; i < n; ++i)
556     hash = 5 * hash + (unsigned) s[i];
557   return hash;
558 }
559 
560 void __cdecl s_get_a_bstr(bstr_t *b)
561 {
562   bstr_t bstr;
563   short str[] = {5, 'W', 'i', 'n', 'e', 0};
564   bstr = HeapAlloc(GetProcessHeap(), 0, sizeof(str));
565   memcpy(bstr, str, sizeof(str));
566   *b = bstr + 1;
567 }
568 
569 void __cdecl s_get_name(name_t *name)
570 {
571   const char bossman[] = "Jeremy White";
572   memcpy(name->name, bossman, min(name->size, sizeof(bossman)));
573   /* ensure nul-termination */
574   if (name->size < sizeof(bossman))
575     name->name[name->size - 1] = 0;
576 }
577 
578 void __cdecl s_get_names(int *n, str_array_t *names)
579 {
580   str_array_t list;
581 
582   list = MIDL_user_allocate(2 * sizeof(list[0]));
583   list[0] = MIDL_user_allocate(6);
584   strcpy(list[0], "Hello");
585   list[1] = MIDL_user_allocate(7);
586   strcpy(list[1], "World!");
587 
588   *names = list;
589   *n = 2;
590 }
591 
592 void __cdecl s_get_namesw(int *n, wstr_array_t *names)
593 {
594   wstr_array_t list;
595 
596   list = MIDL_user_allocate(2 * sizeof(list[0]));
597   list[0] = MIDL_user_allocate(sizeof(helloW));
598   lstrcpyW(list[0], helloW);
599   list[1] = MIDL_user_allocate(sizeof(worldW));
600   lstrcpyW(list[1], worldW);
601 
602   *names = list;
603   *n = 2;
604 }
605 
606 int __cdecl s_sum_pcarr2(int n, int **pa)
607 {
608   return s_sum_conf_array(*pa, n);
609 }
610 
611 int __cdecl s_sum_L1_norms(int n, vector_t *vs)
612 {
613   int i;
614   int sum = 0;
615   for (i = 0; i < n; ++i)
616     sum += abs(vs[i].x) + abs(vs[i].y) + abs(vs[i].z);
617   return sum;
618 }
619 
620 s123_t * __cdecl s_get_s123(void)
621 {
622   s123_t *s = MIDL_user_allocate(sizeof *s);
623   s->f1 = 1;
624   s->f2 = 2;
625   s->f3 = 3;
626   return s;
627 }
628 
629 str_t __cdecl s_get_filename(void)
630 {
631     return (char *)__FILE__;
632 }
633 
634 int __cdecl s_echo_ranged_int(int i, int j, int k)
635 {
636     return min( 100, i + j + k );
637 }
638 
639 int __cdecl s_echo_ranged_int2(int i)
640 {
641     return i;
642 }
643 
644 void __cdecl s_get_ranged_enum(renum_t *re)
645 {
646     *re = RE3;
647 }
648 
649 void __cdecl s_context_handle_test(void)
650 {
651     NDR_SCONTEXT h;
652     RPC_BINDING_HANDLE binding;
653     RPC_STATUS status;
654     unsigned char buf[20];
655     static RPC_SERVER_INTERFACE server_if =
656     {
657         sizeof(RPC_SERVER_INTERFACE),
658         {{0x00000000,0x4114,0x0704,{0x23,0x01,0x00,0x00,0x00,0x00,0x00,0x00}},{1,0}},
659         {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
660         NULL,
661         0,
662         0,
663         0,
664         0,
665         0,
666     };
667 
668     binding = I_RpcGetCurrentCallHandle();
669     ok(binding != NULL, "I_RpcGetCurrentCallHandle returned NULL\n");
670 
671     if (!pNDRSContextMarshall2 || !pNDRSContextUnmarshall2)
672     {
673         win_skip("NDRSContextMarshall2 or NDRSContextUnmarshall2 not exported from rpcrt4.dll\n");
674         return;
675     }
676 
677     h = pNDRSContextUnmarshall2(binding, NULL, NDR_LOCAL_DATA_REPRESENTATION, NULL, 0);
678     ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n");
679 
680     /* marshal a context handle with NULL userContext */
681     memset(buf, 0xcc, sizeof(buf));
682     pNDRSContextMarshall2(binding, h, buf, NULL, NULL, 0);
683     ok(*(ULONG *)buf == 0, "attributes should have been set to 0 instead of 0x%x\n", *(ULONG *)buf);
684     ok(UuidIsNil((UUID *)&buf[4], &status), "uuid should have been nil\n");
685 
686     h = pNDRSContextUnmarshall2(binding, NULL, NDR_LOCAL_DATA_REPRESENTATION, NULL, 0);
687     ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n");
688 
689     /* marshal a context handle with non-NULL userContext */
690     memset(buf, 0xcc, sizeof(buf));
691     h->userContext = (void *)0xdeadbeef;
692     pNDRSContextMarshall2(binding, h, buf, NULL, NULL, 0);
693     ok(*(ULONG *)buf == 0, "attributes should have been set to 0 instead of 0x%x\n", *(ULONG *)buf);
694     ok(!UuidIsNil((UUID *)&buf[4], &status), "uuid should not have been nil\n");
695 
696     /* raises ERROR_INVALID_HANDLE exception on Vista upwards */
697     if (0)
698     {
699     h = pNDRSContextUnmarshall2(binding, buf, NDR_LOCAL_DATA_REPRESENTATION, NULL, 0);
700     ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n");
701     ok(h->userContext == (void *)0xdeadbeef, "userContext of interface didn't unmarshal properly: %p\n", h->userContext);
702 
703     /* marshal a context handle with an interface specified */
704     h = pNDRSContextUnmarshall2(binding, NULL, NDR_LOCAL_DATA_REPRESENTATION, &server_if.InterfaceId, 0);
705     ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n");
706 
707     memset(buf, 0xcc, sizeof(buf));
708     h->userContext = (void *)0xcafebabe;
709     pNDRSContextMarshall2(binding, h, buf, NULL, &server_if.InterfaceId, 0);
710     ok(*(ULONG *)buf == 0, "attributes should have been set to 0 instead of 0x%x\n", *(ULONG *)buf);
711     ok(!UuidIsNil((UUID *)&buf[4], &status), "uuid should not have been nil\n");
712 
713     h = pNDRSContextUnmarshall2(binding, buf, NDR_LOCAL_DATA_REPRESENTATION, &server_if.InterfaceId, 0);
714     ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n");
715     ok(h->userContext == (void *)0xcafebabe, "userContext of interface didn't unmarshal properly: %p\n", h->userContext);
716     }
717 
718     /* test same interface data, but different pointer */
719     /* raises ERROR_INVALID_HANDLE exception */
720     if (0)
721     {
722         RPC_SERVER_INTERFACE server_if_clone = server_if;
723 
724         pNDRSContextUnmarshall2(binding, buf, NDR_LOCAL_DATA_REPRESENTATION, &server_if_clone.InterfaceId, 0);
725     }
726 
727     /* test different interface data, but different pointer */
728     /* raises ERROR_INVALID_HANDLE exception */
729     if (0)
730     {
731         static RPC_SERVER_INTERFACE server_if2 =
732         {
733             sizeof(RPC_SERVER_INTERFACE),
734             {{0x00000000,0x4114,0x0704,{0x23,0x01,0x00,0x00,0x00,0x00,0x00,0x00}},{1,0}},
735             {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},
736             NULL,
737             0,
738             0,
739             0,
740             0,
741             0,
742         };
743         pNDRSContextMarshall2(binding, h, buf, NULL, &server_if.InterfaceId, 0);
744 
745         pNDRSContextUnmarshall2(binding, buf, NDR_LOCAL_DATA_REPRESENTATION, &server_if2.InterfaceId, 0);
746     }
747 
748     binding = NULL;
749     status = RpcBindingServerFromClient(NULL, &binding);
750 
751     ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
752     ok(binding != NULL, "binding is NULL\n");
753 
754     if (status == RPC_S_OK && binding != NULL)
755     {
756         unsigned char* string_binding = NULL;
757         unsigned char* object_uuid = NULL;
758         unsigned char* protseq = NULL;
759         unsigned char* network_address = NULL;
760         unsigned char* endpoint = NULL;
761         unsigned char* network_options = NULL;
762 
763         status = RpcBindingToStringBindingA(binding, &string_binding);
764         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
765         ok(string_binding != NULL, "string_binding is NULL\n");
766 
767         status = RpcStringBindingParseA(string_binding, &object_uuid, &protseq, &network_address, &endpoint, &network_options);
768         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
769         ok(protseq != NULL && *protseq != '\0', "protseq is %s\n", protseq);
770         ok(network_address != NULL && *network_address != '\0', "network_address is %s\n", network_address);
771 
772         todo_wine
773         {
774             ok(object_uuid != NULL && *object_uuid == '\0', "object_uuid is %s\n", object_uuid);
775             ok(endpoint != NULL && *endpoint == '\0', "endpoint is %s\n", endpoint);
776             ok(network_options != NULL && *network_options == '\0', "network_options is %s\n", network_options);
777         }
778 
779         RpcStringFreeA(&string_binding);
780         RpcStringFreeA(&object_uuid);
781         RpcStringFreeA(&protseq);
782         RpcStringFreeA(&network_address);
783         RpcStringFreeA(&endpoint);
784         RpcStringFreeA(&network_options);
785         RpcBindingFree(&binding);
786     }
787 }
788 
789 void __cdecl s_get_numbers(int length, int size, pints_t n[])
790 {
791     int i;
792     for (i = 0; i < length; i++)
793     {
794         n[i].pi = midl_user_allocate(sizeof(*n[i].pi));
795         *n[i].pi = i;
796         n[i].ppi = NULL;
797         n[i].pppi = NULL;
798     }
799 }
800 
801 void __cdecl s_get_numbers_struct(numbers_struct_t **ns)
802 {
803     int i;
804     *ns = midl_user_allocate(FIELD_OFFSET(numbers_struct_t, numbers[5]));
805     if (!*ns) return;
806     (*ns)->length = 5;
807     (*ns)->size = 5;
808     for (i = 0; i < (*ns)->length; i++)
809     {
810         (*ns)->numbers[i].pi = NULL;
811         (*ns)->numbers[i].ppi = NULL;
812         (*ns)->numbers[i].pppi = NULL;
813     }
814     (*ns)->numbers[0].pi = midl_user_allocate(sizeof(*(*ns)->numbers[i].pi));
815     *(*ns)->numbers[0].pi = 5;
816 }
817 
818 void __cdecl s_full_pointer_test(int *a, int *b)
819 {
820     ok(*a == 42, "Expected *a to be 42 instead of %d\n", *a);
821     ok(*b == 42, "Expected *b to be 42 instead of %d\n", *a);
822     ok(a == b, "Expected a (%p) to point to the same memory as b (%p)\n", a, b);
823 }
824 
825 void __cdecl s_full_pointer_null_test(int *a, int *b)
826 {
827     ok(*a == 42, "Expected *a to be 42 instead of %d\n", *a);
828     ok(b == NULL, "Expected b to be NULL instead of %p\n", b);
829 }
830 
831 void __cdecl s_stop(void)
832 {
833   if (!stop_wait_event)
834   {
835     ok(RPC_S_OK == RpcMgmtStopServerListening(NULL), "RpcMgmtStopServerListening\n");
836     ok(RPC_S_OK == RpcServerUnregisterIf(NULL, NULL, FALSE), "RpcServerUnregisterIf\n");
837   }
838   ok(SetEvent(stop_event), "SetEvent\n");
839   if (stop_wait_event)
840   {
841     DWORD ret;
842     ret = WaitForSingleObject(stop_wait_event, 10000);
843     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
844   }
845 }
846 
847 void __cdecl s_stop_autolisten(void)
848 {
849     RPC_STATUS status;
850     status = RpcServerUnregisterIf(NULL, NULL, FALSE);
851 todo_wine
852     ok(status == RPC_S_UNKNOWN_MGR_TYPE, "got %u\n", status);
853 }
854 
855 void __cdecl s_ip_test(ipu_t *a)
856 {
857     STATSTG st;
858     HRESULT hr;
859 
860     hr = IStream_Stat(a->tagged_union.stream, &st, STATFLAG_NONAME);
861     ok(hr == S_OK, "got %#x\n", hr);
862 }
863 
864 int __cdecl s_sum_ptr_array(int *a[2])
865 {
866     return *a[0] + *a[1];
867 }
868 
869 int __cdecl s_sum_array_ptr(int (*a)[2])
870 {
871     return (*a)[0] + (*a)[1];
872 }
873 
874 static void
875 make_cmdline(char buffer[MAX_PATH], const char *test)
876 {
877   sprintf(buffer, "%s server %s", progname, test);
878 }
879 
880 static void
881 run_client(const char *test)
882 {
883   char cmdline[MAX_PATH];
884   PROCESS_INFORMATION info;
885   STARTUPINFOA startup;
886 
887   memset(&startup, 0, sizeof startup);
888   startup.cb = sizeof startup;
889 
890   make_cmdline(cmdline, test);
891   ok(CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
892   winetest_wait_child_process( info.hProcess );
893   ok(CloseHandle(info.hProcess), "CloseHandle\n");
894   ok(CloseHandle(info.hThread), "CloseHandle\n");
895 }
896 
897 static void
898 basic_tests(void)
899 {
900   char string[] = "I am a string";
901   WCHAR wstring[] = {'I',' ','a','m',' ','a',' ','w','s','t','r','i','n','g', 0};
902   int f[5] = {1, 3, 0, -2, -4};
903   vector_t a = {1, 3, 7};
904   vector_t vec1 = {4, -2, 1}, vec2 = {-5, 2, 3}, *pvec2 = &vec2;
905   pvectors_t pvecs = {&vec1, &pvec2};
906   sp_inner_t spi = {42};
907   sp_t sp = {-13, &spi};
908   aligns_t aligns;
909   pints_t pints;
910   ptypes_t ptypes;
911   padded_t padded;
912   padded_t padded2[2];
913   bogus_t bogus;
914   int i1, i2, i3, *pi2, *pi3, **ppi3;
915   double u, v;
916   float s, t;
917   LONG q, r;
918   short h;
919   char c;
920   int x;
921   hyper y;
922   str_struct_t ss = {string};
923   wstr_struct_t ws = {wstring};
924   str_t str;
925   se_t se;
926   renum_t re;
927 
928   ok(int_return() == INT_CODE, "RPC int_return\n");
929 
930   ok(square(7) == 49, "RPC square\n");
931   x = sum(23, -4);
932   ok(x == 19, "RPC sum got %d\n", x);
933   c = sum_char(-23, 50);
934   ok(c == 27, "RPC sum_char got %d\n", (int)c);
935   h = sum_short(1122, -344);
936   ok(h == 778, "RPC sum_short got %d\n", (int)h);
937   x = sum_float(123.45, -32.2);
938   ok(x == 91, "RPC sum_float got %d\n", x);
939   x = sum_double_int(-78, 148.46);
940   ok(x == 70, "RPC sum_double_int got %d\n", x);
941   y = sum_hyper((hyper)0x12345678 << 16, (hyper)0x33557799 << 16);
942   ok(y == (hyper)0x4589ce11 << 16, "RPC hyper got %s\n", wine_dbgstr_longlong(y));
943   x = sum_hyper_int((hyper)0x24242424 << 16, -((hyper)0x24241212 << 16));
944   ok(x == 0x12120000, "RPC hyper_int got 0x%x\n", x);
945   x = sum_char_hyper( 12, ((hyper)0x42424242 << 32) | 0x33334444 );
946   ok(x == 0x33334450, "RPC char_hyper got 0x%x\n", x);
947 
948   x = 0;
949   square_out(11, &x);
950   ok(x == 121, "RPC square_out\n");
951 
952   x = 5;
953   square_ref(&x);
954   ok(x == 25, "RPC square_ref\n");
955 
956   ok(str_length(string) == strlen(string), "RPC str_length\n");
957   ok(str_t_length(string) == strlen(string), "RPC str_length\n");
958   ok(dot_self(&a) == 59, "RPC dot_self\n");
959 
960   ok(str_struct_len(&ss) == lstrlenA(string), "RPC str_struct_len\n");
961   ok(wstr_struct_len(&ws) == lstrlenW(wstring), "RPC str_struct_len\n");
962 
963   v = 0.0;
964   u = square_half(3.0, &v);
965   ok(u == 9.0, "RPC square_half\n");
966   ok(v == 1.5, "RPC square_half\n");
967 
968   t = 0.0f;
969   s = square_half_float(3.0f, &t);
970   ok(s == 9.0f, "RPC square_half_float\n");
971   ok(t == 1.5f, "RPC square_half_float\n");
972 
973   r = 0;
974   q = square_half_long(3, &r);
975   ok(q == 9, "RPC square_half_long\n");
976   ok(r == 1, "RPC square_half_long\n");
977 
978   i1 = 19;
979   i2 = -3;
980   i3 = -29;
981   pi2 = &i2;
982   pi3 = &i3;
983   ppi3 = &pi3;
984   pints.pi = &i1;
985   pints.ppi = &pi2;
986   pints.pppi = &ppi3;
987   ok(pints_sum(&pints) == -13, "RPC pints_sum\n");
988 
989   c = 10;
990   h = 3;
991   q = 14;
992   s = -5.0f;
993   u = 11.0;
994   ptypes.pc = &c;
995   ptypes.ps = &h;
996   ptypes.pl = &q;
997   ptypes.pf = &s;
998   ptypes.pd = &u;
999   ok(ptypes_sum(&ptypes) == 33.0, "RPC ptypes_sum\n");
1000 
1001   ok(dot_pvectors(&pvecs) == -21, "RPC dot_pvectors\n");
1002   ok(dot_copy_vectors(vec1, vec2) == -21, "RPC dot_copy_vectors\n");
1003   ok(sum_fixed_array(f) == -2, "RPC sum_fixed_array\n");
1004   ok(sum_sp(&sp) == 29, "RPC sum_sp\n");
1005 
1006   ok(enum_ord(E1) == 1, "RPC enum_ord\n");
1007   ok(enum_ord(E2) == 2, "RPC enum_ord\n");
1008   ok(enum_ord(E3) == 3, "RPC enum_ord\n");
1009   ok(enum_ord(E4) == 4, "RPC enum_ord\n");
1010 
1011   se.f = E2;
1012   check_se2(&se);
1013 
1014   memset(&aligns, 0, sizeof(aligns));
1015   aligns.c = 3;
1016   aligns.i = 4;
1017   aligns.s = 5;
1018   aligns.d = 6.0;
1019   ok(sum_aligns(&aligns) == 18.0, "RPC sum_aligns\n");
1020 
1021   padded.i = -3;
1022   padded.c = 8;
1023   ok(sum_padded(&padded) == 5, "RPC sum_padded\n");
1024   padded2[0].i = -5;
1025   padded2[0].c = 1;
1026   padded2[1].i = 3;
1027   padded2[1].c = 7;
1028   ok(sum_padded2(padded2) == 6, "RPC sum_padded2\n");
1029   padded2[0].i = -5;
1030   padded2[0].c = 1;
1031   padded2[1].i = 3;
1032   padded2[1].c = 7;
1033   ok(sum_padded_conf(padded2, 2) == 6, "RPC sum_padded_conf\n");
1034 
1035   i1 = 14;
1036   i2 = -7;
1037   i3 = -4;
1038   bogus.h.p1 = &i1;
1039   bogus.p2 = &i2;
1040   bogus.p3 = &i3;
1041   bogus.c = 9;
1042   ok(sum_bogus(&bogus) == 12, "RPC sum_bogus\n");
1043 
1044   check_null(NULL);
1045 
1046   str = get_filename();
1047   ok(!strcmp(str, __FILE__), "get_filename() returned %s instead of %s\n", str, __FILE__);
1048   midl_user_free(str);
1049 
1050   x = echo_ranged_int(0,0,0);
1051   ok(x == 0, "echo_ranged_int() returned %d instead of 0\n", x);
1052   x = echo_ranged_int(10,20,100);
1053   ok(x == 100, "echo_ranged_int() returned %d instead of 100\n", x);
1054   x = echo_ranged_int2(40);
1055   ok(x == 40, "echo_ranged_int() returned %d instead of 40\n", x);
1056 
1057   if (!old_windows_version)
1058   {
1059       re = 0xdeadbeef;
1060       get_ranged_enum(&re);
1061       ok(re == RE3 ||
1062          broken(re == MAKELONG(re, 0xdead)), /* Win 8, Win 10 */
1063          "get_ranged_enum() returned %x instead of RE3\n", re);
1064   }
1065 }
1066 
1067 static void
1068 union_tests(void)
1069 {
1070   encue_t eue;
1071   encu_t eu;
1072   unencu_t uneu;
1073   sun_t su;
1074   ipu_t ipu;
1075   LONG ref;
1076   int i;
1077 
1078   su.s = SUN_I;
1079   su.u.i = 9;
1080   ok(square_sun(&su) == 81.0, "RPC square_sun\n");
1081 
1082   su.s = SUN_F1;
1083   su.u.f = 5.0;
1084   ok(square_sun(&su) == 25.0, "RPC square_sun\n");
1085 
1086   su.s = SUN_F2;
1087   su.u.f = -2.0;
1088   ok(square_sun(&su) == 4.0, "RPC square_sun\n");
1089 
1090   su.s = SUN_PI;
1091   su.u.pi = &i;
1092   i = 11;
1093   ok(square_sun(&su) == 121.0, "RPC square_sun\n");
1094 
1095   eu.t = ENCU_I;
1096   eu.tagged_union.i = 7;
1097   ok(square_encu(&eu) == 49.0, "RPC square_encu\n");
1098 
1099   eu.t = ENCU_F;
1100   eu.tagged_union.f = 3.0;
1101   ok(square_encu(&eu) == 9.0, "RPC square_encu\n");
1102 
1103   uneu.i = 4;
1104   ok(square_unencu(ENCU_I, &uneu) == 16.0, "RPC square_unencu\n");
1105 
1106   uneu.f = 5.0;
1107   ok(square_unencu(ENCU_F, &uneu) == 25.0, "RPC square_unencu\n");
1108 
1109   eue.t = E1;
1110   eue.tagged_union.i1 = 8;
1111   ok(square_encue(&eue) == 64.0, "RPC square_encue\n");
1112 
1113   eue.t = E2;
1114   eue.tagged_union.f2 = 10.0;
1115   ok(square_encue(&eue) == 100.0, "RPC square_encue\n");
1116 
1117   CoInitializeEx(NULL, COINIT_MULTITHREADED);
1118 
1119   CreateStreamOnHGlobal(NULL, TRUE, &ipu.tagged_union.stream);
1120   ip_test(&ipu);
1121   ref = IStream_Release(ipu.tagged_union.stream);
1122   ok(!ref, "got %u refs\n", ref);
1123 
1124   CoUninitialize();
1125 }
1126 
1127 static test_list_t *
1128 null_list(void)
1129 {
1130   test_list_t *n = HeapAlloc(GetProcessHeap(), 0, sizeof *n);
1131   n->t = TL_NULL;
1132   n->u.x = 0;
1133   return n;
1134 }
1135 
1136 static test_list_t *
1137 make_list(test_list_t *tail)
1138 {
1139   test_list_t *n = HeapAlloc(GetProcessHeap(), 0, sizeof *n);
1140   n->t = TL_LIST;
1141   n->u.tail = tail;
1142   return n;
1143 }
1144 
1145 static void
1146 free_list(test_list_t *list)
1147 {
1148   if (list->t == TL_LIST)
1149     free_list(list->u.tail);
1150   HeapFree(GetProcessHeap(), 0, list);
1151 }
1152 
1153 ULONG __RPC_USER
1154 puint_t_UserSize(ULONG *flags, ULONG start, puint_t *p)
1155 {
1156   return start + sizeof(int);
1157 }
1158 
1159 unsigned char * __RPC_USER
1160 puint_t_UserMarshal(ULONG *flags, unsigned char *buffer, puint_t *p)
1161 {
1162   int n = atoi(*p);
1163   memcpy(buffer, &n, sizeof n);
1164   return buffer + sizeof n;
1165 }
1166 
1167 unsigned char * __RPC_USER
1168 puint_t_UserUnmarshal(ULONG *flags, unsigned char *buffer, puint_t *p)
1169 {
1170   int n;
1171   memcpy(&n, buffer, sizeof n);
1172   *p = HeapAlloc(GetProcessHeap(), 0, 10);
1173   sprintf(*p, "%d", n);
1174   return buffer + sizeof n;
1175 }
1176 
1177 void __RPC_USER
1178 puint_t_UserFree(ULONG *flags, puint_t *p)
1179 {
1180   HeapFree(GetProcessHeap(), 0, *p);
1181 }
1182 
1183 ULONG __RPC_USER
1184 us_t_UserSize(ULONG *flags, ULONG start, us_t *pus)
1185 {
1186   return start + sizeof(struct wire_us);
1187 }
1188 
1189 unsigned char * __RPC_USER
1190 us_t_UserMarshal(ULONG *flags, unsigned char *buffer, us_t *pus)
1191 {
1192   struct wire_us wus;
1193   wus.x = atoi(pus->x);
1194   memcpy(buffer, &wus, sizeof wus);
1195   return buffer + sizeof wus;
1196 }
1197 
1198 unsigned char * __RPC_USER
1199 us_t_UserUnmarshal(ULONG *flags, unsigned char *buffer, us_t *pus)
1200 {
1201   struct wire_us wus;
1202   memcpy(&wus, buffer, sizeof wus);
1203   pus->x = HeapAlloc(GetProcessHeap(), 0, 10);
1204   sprintf(pus->x, "%d", wus.x);
1205   return buffer + sizeof wus;
1206 }
1207 
1208 void __RPC_USER
1209 us_t_UserFree(ULONG *flags, us_t *pus)
1210 {
1211   HeapFree(GetProcessHeap(), 0, pus->x);
1212 }
1213 
1214 ULONG __RPC_USER
1215 bstr_t_UserSize(ULONG *flags, ULONG start, bstr_t *b)
1216 {
1217   return start + FIELD_OFFSET(user_bstr_t, data[(*b)[-1]]);
1218 }
1219 
1220 unsigned char * __RPC_USER
1221 bstr_t_UserMarshal(ULONG *flags, unsigned char *buffer, bstr_t *b)
1222 {
1223   wire_bstr_t wb = (wire_bstr_t) buffer;
1224   wb->n = (*b)[-1];
1225   memcpy(&wb->data, *b, wb->n * sizeof wb->data[0]);
1226   return buffer + FIELD_OFFSET(user_bstr_t, data[wb->n]);
1227 }
1228 
1229 unsigned char * __RPC_USER
1230 bstr_t_UserUnmarshal(ULONG *flags, unsigned char *buffer, bstr_t *b)
1231 {
1232   wire_bstr_t wb = (wire_bstr_t) buffer;
1233   short *data = HeapAlloc(GetProcessHeap(), 0, (wb->n + 1) * sizeof *data);
1234   data[0] = wb->n;
1235   memcpy(&data[1], wb->data, wb->n * sizeof data[1]);
1236   *b = &data[1];
1237   return buffer + FIELD_OFFSET(user_bstr_t, data[wb->n]);
1238 }
1239 
1240 void __RPC_USER
1241 bstr_t_UserFree(ULONG *flags, bstr_t *b)
1242 {
1243   HeapFree(GetProcessHeap(), 0, &((*b)[-1]));
1244 }
1245 
1246 static void
1247 pointer_tests(void)
1248 {
1249   int a[] = {1, 2, 3, 4};
1250   char p1[] = "11";
1251   test_list_t *list = make_list(make_list(make_list(null_list())));
1252   test_us_t tus = {{p1}};
1253   int *pa[4];
1254   puints_t pus;
1255   cpuints_t cpus;
1256   short bstr_data[] = { 5, 'H', 'e', 'l', 'l', 'o' };
1257   bstr_t bstr = &bstr_data[1], bstr2;
1258   name_t name;
1259   void *buffer;
1260   int *pa2;
1261   s123_t *s123;
1262   int val = 42;
1263 
1264   ok(test_list_length(list) == 3, "RPC test_list_length\n");
1265   ok(square_puint(p1) == 121, "RPC square_puint\n");
1266   pus.n = 4;
1267   pus.ps = HeapAlloc(GetProcessHeap(), 0, pus.n * sizeof pus.ps[0]);
1268   pus.ps[0] = xstrdup("5");
1269   pus.ps[1] = xstrdup("6");
1270   pus.ps[2] = xstrdup("7");
1271   pus.ps[3] = xstrdup("8");
1272   ok(sum_puints(&pus) == 26, "RPC sum_puints\n");
1273   HeapFree(GetProcessHeap(), 0, pus.ps[0]);
1274   HeapFree(GetProcessHeap(), 0, pus.ps[1]);
1275   HeapFree(GetProcessHeap(), 0, pus.ps[2]);
1276   HeapFree(GetProcessHeap(), 0, pus.ps[3]);
1277   HeapFree(GetProcessHeap(), 0, pus.ps);
1278   cpus.n = 4;
1279   cpus.ps = HeapAlloc(GetProcessHeap(), 0, cpus.n * sizeof cpus.ps[0]);
1280   cpus.ps[0] = xstrdup("5");
1281   cpus.ps[1] = xstrdup("6");
1282   cpus.ps[2] = xstrdup("7");
1283   cpus.ps[3] = xstrdup("8");
1284   ok(sum_cpuints(&cpus) == 26, "RPC sum_puints\n");
1285   HeapFree(GetProcessHeap(), 0, cpus.ps[0]);
1286   HeapFree(GetProcessHeap(), 0, cpus.ps[1]);
1287   HeapFree(GetProcessHeap(), 0, cpus.ps[2]);
1288   HeapFree(GetProcessHeap(), 0, cpus.ps[3]);
1289   HeapFree(GetProcessHeap(), 0, cpus.ps);
1290   ok(square_test_us(&tus) == 121, "RPC square_test_us\n");
1291 
1292   pa[0] = &a[0];
1293   pa[1] = &a[1];
1294   pa[2] = &a[2];
1295   ok(sum_parr(pa) == 6, "RPC sum_parr\n");
1296 
1297   pa[0] = &a[0];
1298   pa[1] = &a[1];
1299   pa[2] = &a[2];
1300   pa[3] = &a[3];
1301   ok(sum_pcarr(pa, 4) == 10, "RPC sum_pcarr\n");
1302 
1303   ok(hash_bstr(bstr) == s_hash_bstr(bstr), "RPC hash_bstr_data\n");
1304 
1305   get_a_bstr(&bstr);
1306   s_get_a_bstr(&bstr2);
1307   ok(!lstrcmpW((LPCWSTR)bstr, (LPCWSTR)bstr2), "bstr mismatch\n");
1308   HeapFree(GetProcessHeap(), 0, bstr - 1);
1309   HeapFree(GetProcessHeap(), 0, bstr2 - 1);
1310 
1311   free_list(list);
1312 
1313   if (!old_windows_version)
1314   {
1315       int n;
1316       str_array_t names;
1317       wstr_array_t namesw;
1318 
1319       name.size = 10;
1320       name.name = buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, name.size);
1321       get_name(&name);
1322       ok(name.name == buffer, "[in,out] pointer should have stayed as %p but instead changed to %p\n", name.name, buffer);
1323       ok(!strcmp(name.name, "Jeremy Wh"), "name didn't unmarshall properly, expected \"Jeremy Wh\", but got \"%s\"\n", name.name);
1324       HeapFree(GetProcessHeap(), 0, name.name);
1325 
1326       n = -1;
1327       names = NULL;
1328       get_names(&n, &names);
1329       ok(n == 2, "expected 2, got %d\n", n);
1330       ok(!strcmp(names[0], "Hello"), "expected Hello, got %s\n", names[0]);
1331       ok(!strcmp(names[1], "World!"), "expected World!, got %s\n", names[1]);
1332       MIDL_user_free(names[0]);
1333       MIDL_user_free(names[1]);
1334       MIDL_user_free(names);
1335 
1336       n = -1;
1337       namesw = NULL;
1338       get_namesw(&n, &namesw);
1339       ok(n == 2, "expected 2, got %d\n", n);
1340       ok(!lstrcmpW(namesw[0], helloW), "expected Hello, got %s\n", wine_dbgstr_w(namesw[0]));
1341       ok(!lstrcmpW(namesw[1], worldW), "expected World!, got %s\n", wine_dbgstr_w(namesw[1]));
1342       MIDL_user_free(namesw[0]);
1343       MIDL_user_free(namesw[1]);
1344       MIDL_user_free(namesw);
1345   }
1346 
1347   pa2 = a;
1348   ok(sum_pcarr2(4, &pa2) == 10, "RPC sum_pcarr2\n");
1349 
1350   s123 = get_s123();
1351   ok(s123->f1 == 1 && s123->f2 == 2 && s123->f3 == 3, "RPC get_s123\n");
1352   MIDL_user_free(s123);
1353 
1354   full_pointer_test(&val, &val);
1355   full_pointer_null_test(&val, NULL);
1356 }
1357 
1358 static int
1359 check_pyramid_doub_carr(doub_carr_t *dc)
1360 {
1361   int i, j;
1362   for (i = 0; i < dc->n; ++i)
1363     for (j = 0; j < dc->a[i]->n; ++j)
1364       if (dc->a[i]->a[j] != j + 1)
1365         return FALSE;
1366   return TRUE;
1367 }
1368 
1369 static void
1370 free_pyramid_doub_carr(doub_carr_t *dc)
1371 {
1372   int i;
1373   for (i = 0; i < dc->n; ++i)
1374     MIDL_user_free(dc->a[i]);
1375   MIDL_user_free(dc);
1376 }
1377 
1378 static void
1379 array_tests(void)
1380 {
1381   int m[2][3][4] =
1382   {
1383     {{1, 2, 3, 4}, {-1, -3, -5, -7}, {0, 2, 4, 6}},
1384     {{1, -2, 3, -4}, {2, 3, 5, 7}, {-4, -1, -14, 4114}}
1385   };
1386   int c[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1387   int c2[] = {10, 100, 200};
1388   int c3[20];
1389   vector_t vs[2] = {{1, -2, 3}, {4, -5, -6}};
1390   cps_t cps;
1391   cpsc_t cpsc;
1392   cs_t *cs;
1393   int n;
1394   int ca[5] = {1, -2, 3, -4, 5};
1395   int tmp[10];
1396   doub_carr_t *dc;
1397   int *pi;
1398   pints_t api[5];
1399   numbers_struct_t *ns;
1400   refpint_t rpi[5];
1401   int i0 = 1, i1 = 2, *ptr_array[2] = {&i0, &i1}, array[2] = {3, 4};
1402 
1403   if (!old_windows_version)
1404   {
1405       const char str1[25] = "Hello";
1406       ok(cstr_length(str1, sizeof str1) == strlen(str1), "RPC cstr_length\n");
1407   }
1408 
1409   ok(sum_fixed_int_3d(m) == 4116, "RPC sum_fixed_int_3d\n");
1410 
1411   ok(sum_conf_array(c, 10) == 45, "RPC sum_conf_array\n");
1412   ok(sum_conf_array(&c[5], 2) == 11, "RPC sum_conf_array\n");
1413   ok(sum_conf_array(&c[7], 1) == 7, "RPC sum_conf_array\n");
1414   ok(sum_conf_array(&c[2], 0) == 0, "RPC sum_conf_array\n");
1415 
1416   ok(sum_conf_ptr_by_conf_ptr(1, c2, c) == 45, "RPC sum_conf_ptr_by_conf_ptr\n");
1417   ok(sum_conf_ptr_by_conf_ptr(3, c2, c) == 345, "RPC sum_conf_ptr_by_conf_ptr\n");
1418   c2[0] = 0;
1419   ok(sum_conf_ptr_by_conf_ptr(3, c2, c) == 300, "RPC sum_conf_ptr_by_conf_ptr\n");
1420 
1421   ok(sum_unique_conf_array(ca, 4) == -2, "RPC sum_unique_conf_array\n");
1422   ok(sum_unique_conf_ptr(ca, 5) == 3, "RPC sum_unique_conf_array\n");
1423   ok(sum_unique_conf_ptr(NULL, 10) == 0, "RPC sum_unique_conf_array\n");
1424 
1425   get_number_array(c3, &n);
1426   ok(n == 10, "RPC get_num_array\n");
1427   for (; n > 0; n--)
1428     ok(c3[n-1] == c[n-1], "get_num_array returned wrong value %d @ %d\n",
1429        c3[n-1], n);
1430   ok(sum_var_array(c, 10) == 45, "RPC sum_conf_array\n");
1431   ok(sum_var_array(&c[5], 2) == 11, "RPC sum_conf_array\n");
1432   ok(sum_var_array(&c[7], 1) == 7, "RPC sum_conf_array\n");
1433   ok(sum_var_array(&c[2], 0) == 0, "RPC sum_conf_array\n");
1434 
1435   ok(dot_two_vectors(vs) == -4, "RPC dot_two_vectors\n");
1436   cs = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(cs_t, ca[5]));
1437   cs->n = 5;
1438   cs->ca[0] = 3;
1439   cs->ca[1] = 5;
1440   cs->ca[2] = -2;
1441   cs->ca[3] = -1;
1442   cs->ca[4] = -4;
1443   ok(sum_cs(cs) == 1, "RPC sum_cs\n");
1444   HeapFree(GetProcessHeap(), 0, cs);
1445 
1446   n = 5;
1447   cps.pn = &n;
1448   cps.ca1 = &c[2];
1449   cps.n = 3;
1450   cps.ca2 = &c[3];
1451   ok(sum_cps(&cps) == 53, "RPC sum_cps\n");
1452 
1453   cpsc.a = 4;
1454   cpsc.b = 5;
1455   cpsc.c = 1;
1456   cpsc.ca = c;
1457   ok(sum_cpsc(&cpsc) == 6, "RPC sum_cpsc\n");
1458   cpsc.a = 4;
1459   cpsc.b = 5;
1460   cpsc.c = 0;
1461   cpsc.ca = c;
1462   ok(sum_cpsc(&cpsc) == 10, "RPC sum_cpsc\n");
1463 
1464   cpsc.ca = NULL;
1465   ok(get_cpsc(5, &cpsc) == 45, "RPC sum_cpsc\n");
1466   ok( cpsc.a == 10, "RPC get_cpsc %u\n", cpsc.a );
1467   for (n = 0; n < 10; n++) ok( cpsc.ca[n] == n, "RPC get_cpsc[%d] = %d\n", n, cpsc.ca[n] );
1468 
1469   memset( tmp, 0x33, sizeof(tmp) );
1470   cpsc.ca = tmp;
1471   ok(get_cpsc(4, &cpsc) == 28, "RPC sum_cpsc\n");
1472   ok( cpsc.a == 8, "RPC get_cpsc %u\n", cpsc.a );
1473   ok( cpsc.ca == tmp, "RPC get_cpsc %p/%p\n", cpsc.ca, tmp );
1474   for (n = 0; n < 8; n++) ok( cpsc.ca[n] == n, "RPC get_cpsc[%d] = %d\n", n, cpsc.ca[n] );
1475 
1476   ok(sum_toplev_conf_2n(c, 3) == 15, "RPC sum_toplev_conf_2n\n");
1477   ok(sum_toplev_conf_cond(c, 5, 6, 1) == 10, "RPC sum_toplev_conf_cond\n");
1478   ok(sum_toplev_conf_cond(c, 5, 6, 0) == 15, "RPC sum_toplev_conf_cond\n");
1479 
1480   dc = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(doub_carr_t, a[2]));
1481   dc->n = 2;
1482   dc->a[0] = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(doub_carr_1_t, a[3]));
1483   dc->a[0]->n = 3;
1484   dc->a[0]->a[0] = 5;
1485   dc->a[0]->a[1] = 1;
1486   dc->a[0]->a[2] = 8;
1487   dc->a[1] = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(doub_carr_1_t, a[2]));
1488   dc->a[1]->n = 2;
1489   dc->a[1]->a[0] = 2;
1490   dc->a[1]->a[1] = 3;
1491   ok(sum_doub_carr(dc) == 19, "RPC sum_doub_carr\n");
1492   HeapFree(GetProcessHeap(), 0, dc->a[0]);
1493   HeapFree(GetProcessHeap(), 0, dc->a[1]);
1494   HeapFree(GetProcessHeap(), 0, dc);
1495 
1496   dc = NULL;
1497   make_pyramid_doub_carr(4, &dc);
1498   ok(check_pyramid_doub_carr(dc), "RPC make_pyramid_doub_carr\n");
1499   free_pyramid_doub_carr(dc);
1500 
1501   ok(sum_L1_norms(2, vs) == 21, "RPC sum_L1_norms\n");
1502 
1503   memset(api, 0, sizeof(api));
1504   pi = HeapAlloc(GetProcessHeap(), 0, sizeof(*pi));
1505   *pi = -1;
1506   api[0].pi = pi;
1507   get_numbers(1, 1, api);
1508   ok(api[0].pi == pi, "RPC conformant varying array [out] pointer changed from %p to %p\n", pi, api[0].pi);
1509   ok(*api[0].pi == 0, "pi unmarshalled incorrectly %d\n", *api[0].pi);
1510 
1511   if (!old_windows_version)
1512   {
1513       ns = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(numbers_struct_t, numbers[5]));
1514       ns->length = 5;
1515       ns->size = 5;
1516       ns->numbers[0].pi = pi;
1517       get_numbers_struct(&ns);
1518       ok(ns->numbers[0].pi == pi, "RPC conformant varying struct embedded pointer changed from %p to %p\n", pi, ns->numbers[0].pi);
1519       ok(*ns->numbers[0].pi == 5, "pi unmarshalled incorrectly %d\n", *ns->numbers[0].pi);
1520       HeapFree(GetProcessHeap(), 0, ns);
1521   }
1522   HeapFree(GetProcessHeap(), 0, pi);
1523 
1524   pi = HeapAlloc(GetProcessHeap(), 0, 5 * sizeof(*pi));
1525   pi[0] = 3;  rpi[0] = &pi[0];
1526   pi[1] = 5;  rpi[1] = &pi[1];
1527   pi[2] = -2; rpi[2] = &pi[2];
1528   pi[3] = -1; rpi[3] = &pi[3];
1529   pi[4] = -4; rpi[4] = &pi[4];
1530   ok(sum_complex_array(5, rpi) == 1, "RPC sum_complex_array\n");
1531   HeapFree(GetProcessHeap(), 0, pi);
1532 
1533   ok(sum_ptr_array(ptr_array) == 3, "RPC sum_ptr_array\n");
1534   ok(sum_array_ptr(&array) == 7, "RPC sum_array_ptr\n");
1535 }
1536 
1537 void __cdecl s_authinfo_test(unsigned int protseq, int secure)
1538 {
1539     RPC_BINDING_HANDLE binding;
1540     RPC_STATUS status;
1541     ULONG level, authnsvc;
1542     RPC_AUTHZ_HANDLE privs;
1543     unsigned char *principal;
1544 
1545     binding = I_RpcGetCurrentCallHandle();
1546     ok(binding != NULL, "I_RpcGetCurrentCallHandle returned NULL\n");
1547 
1548     level = authnsvc = 0xdeadbeef;
1549     privs = (RPC_AUTHZ_HANDLE)0xdeadbeef;
1550     principal = (unsigned char *)0xdeadbeef;
1551 
1552     if (secure || protseq == RPC_PROTSEQ_LRPC)
1553     {
1554         status = RpcBindingInqAuthClientA(binding, &privs, &principal, &level, &authnsvc, NULL);
1555         if (status == RPC_S_CANNOT_SUPPORT)
1556         {
1557             win_skip("RpcBindingInqAuthClientA not supported\n");
1558             return;
1559         }
1560         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1561         ok(privs != (RPC_AUTHZ_HANDLE)0xdeadbeef, "privs unchanged\n");
1562         ok(principal != (unsigned char *)0xdeadbeef, "principal unchanged\n");
1563         if (protseq != RPC_PROTSEQ_LRPC)
1564         {
1565             todo_wine
1566             ok(principal != NULL, "NULL principal\n");
1567         }
1568         if (protseq == RPC_PROTSEQ_LRPC && principal)
1569         {
1570             int len;
1571             char *spn;
1572 
1573             len = WideCharToMultiByte(CP_ACP, 0, (const WCHAR *)privs, -1, NULL, 0, NULL, NULL);
1574             spn = HeapAlloc( GetProcessHeap(), 0, len );
1575             WideCharToMultiByte(CP_ACP, 0, (const WCHAR *)privs, -1, spn, len, NULL, NULL);
1576 
1577             ok(!strcmp(domain_and_user, spn), "expected %s got %s\n", domain_and_user, spn);
1578             HeapFree( GetProcessHeap(), 0, spn );
1579         }
1580         ok(level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY, "level unchanged\n");
1581         ok(authnsvc == RPC_C_AUTHN_WINNT, "authnsvc unchanged\n");
1582         RpcStringFreeA(&principal);
1583 
1584         status = RpcBindingInqAuthClientA(NULL, &privs, &principal, &level, &authnsvc, NULL);
1585         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1586         RpcStringFreeA(&principal);
1587 
1588         status = RpcBindingInqAuthClientExA(NULL, &privs, &principal, &level, &authnsvc, NULL, 0);
1589         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1590         RpcStringFreeA(&principal);
1591 
1592         status = RpcImpersonateClient(NULL);
1593         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1594         status = RpcRevertToSelf();
1595         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1596 
1597     }
1598     else
1599     {
1600         status = RpcBindingInqAuthClientA(binding, &privs, &principal, &level, &authnsvc, NULL);
1601         ok(status == RPC_S_BINDING_HAS_NO_AUTH, "expected RPC_S_BINDING_HAS_NO_AUTH got %u\n", status);
1602         ok(privs == (RPC_AUTHZ_HANDLE)0xdeadbeef, "got %p\n", privs);
1603         ok(principal == (unsigned char *)0xdeadbeef, "got %s\n", principal);
1604         ok(level == 0xdeadbeef, "got %u\n", level);
1605         ok(authnsvc == 0xdeadbeef, "got %u\n", authnsvc);
1606     }
1607 }
1608 
1609 static void
1610 run_tests(void)
1611 {
1612   basic_tests();
1613   union_tests();
1614   pointer_tests();
1615   array_tests();
1616   context_handle_test();
1617 }
1618 
1619 static void
1620 set_auth_info(RPC_BINDING_HANDLE handle)
1621 {
1622     RPC_STATUS status;
1623     RPC_SECURITY_QOS qos;
1624 
1625     qos.Version = 1;
1626     qos.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH;
1627     qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
1628     qos.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
1629 
1630     status = pRpcBindingSetAuthInfoExA(handle, (RPC_CSTR)domain_and_user, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
1631                                        RPC_C_AUTHN_WINNT, NULL, 0, &qos);
1632     ok(status == RPC_S_OK, "RpcBindingSetAuthInfoExA failed %d\n", status);
1633 }
1634 
1635 #define test_is_server_listening(a,b) _test_is_server_listening(__LINE__,a,b)
1636 static void _test_is_server_listening(unsigned line, RPC_BINDING_HANDLE binding, RPC_STATUS expected_status)
1637 {
1638     RPC_STATUS status;
1639     status = RpcMgmtIsServerListening(binding);
1640     ok_(__FILE__,line)(status == expected_status, "RpcMgmtIsServerListening returned %u, expected %u\n",
1641                        status, expected_status);
1642 }
1643 
1644 #define test_is_server_listening2(a,b,c) _test_is_server_listening2(__LINE__,a,b,c)
1645 static void _test_is_server_listening2(unsigned line, RPC_BINDING_HANDLE binding, RPC_STATUS expected_status,
1646         RPC_STATUS expected_status2)
1647 {
1648     RPC_STATUS status;
1649     status = RpcMgmtIsServerListening(binding);
1650     ok_(__FILE__,line)(status == expected_status || status == expected_status2,
1651                        "RpcMgmtIsServerListening returned %u, expected %u or %u\n",
1652                        status, expected_status, expected_status2);
1653 }
1654 
1655 static void
1656 client(const char *test)
1657 {
1658   static unsigned char iptcp[] = "ncacn_ip_tcp";
1659   static unsigned char np[] = "ncacn_np";
1660   static unsigned char ncalrpc[] = "ncalrpc";
1661   static unsigned char address[] = "127.0.0.1";
1662   static unsigned char address_np[] = "\\\\.";
1663   static unsigned char port[] = PORT;
1664   static unsigned char pipe[] = PIPE;
1665   static unsigned char guid[] = "00000000-4114-0704-2301-000000000000";
1666 
1667   unsigned char *binding;
1668 
1669   if (strcmp(test, "tcp_basic") == 0)
1670   {
1671     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, iptcp, address, port, NULL, &binding), "RpcStringBindingCompose\n");
1672     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
1673 
1674     run_tests();
1675     authinfo_test(RPC_PROTSEQ_TCP, 0);
1676     test_is_server_listening2(IServer_IfHandle, RPC_S_OK, RPC_S_ACCESS_DENIED);
1677 
1678     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1679     ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n");
1680   }
1681   else if (strcmp(test, "tcp_secure") == 0)
1682   {
1683     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, iptcp, address, port, NULL, &binding), "RpcStringBindingCompose\n");
1684     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
1685 
1686     set_auth_info(IServer_IfHandle);
1687     authinfo_test(RPC_PROTSEQ_TCP, 1);
1688     test_is_server_listening(IServer_IfHandle, RPC_S_ACCESS_DENIED);
1689 
1690     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1691     ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n");
1692   }
1693   else if (strcmp(test, "ncalrpc_basic") == 0)
1694   {
1695     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding), "RpcStringBindingCompose\n");
1696     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
1697 
1698     run_tests(); /* can cause RPC_X_BAD_STUB_DATA exception */
1699     authinfo_test(RPC_PROTSEQ_LRPC, 0);
1700     test_is_server_listening(IServer_IfHandle, RPC_S_OK);
1701 
1702     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1703     ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n");
1704   }
1705   else if (strcmp(test, "ncalrpc_autolisten") == 0)
1706   {
1707     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding), "RpcStringBindingCompose\n");
1708     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
1709 
1710     run_tests();
1711     authinfo_test(RPC_PROTSEQ_LRPC, 0);
1712 todo_wine
1713     test_is_server_listening(IServer_IfHandle, RPC_S_NOT_LISTENING);
1714 
1715     stop_autolisten();
1716     ok(int_return() == INT_CODE, "RPC int_return\n");
1717 
1718     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1719     ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n");
1720   }
1721   else if (strcmp(test, "ncalrpc_secure") == 0)
1722   {
1723     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding), "RpcStringBindingCompose\n");
1724     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
1725 
1726     set_auth_info(IServer_IfHandle);
1727     authinfo_test(RPC_PROTSEQ_LRPC, 1);
1728     test_is_server_listening(IServer_IfHandle, RPC_S_OK);
1729 
1730     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1731     ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n");
1732   }
1733   else if (strcmp(test, "np_basic") == 0)
1734   {
1735     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding), "RpcStringBindingCompose\n");
1736     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
1737 
1738     test_is_server_listening(IServer_IfHandle, RPC_S_OK);
1739     run_tests();
1740     authinfo_test(RPC_PROTSEQ_NMP, 0);
1741     test_is_server_listening(IServer_IfHandle, RPC_S_OK);
1742     stop();
1743     test_is_server_listening(IServer_IfHandle, RPC_S_NOT_LISTENING);
1744 
1745     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1746     ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n");
1747   }
1748 }
1749 
1750 static void
1751 server(void)
1752 {
1753   static unsigned char iptcp[] = "ncacn_ip_tcp";
1754   static unsigned char port[] = PORT;
1755   static unsigned char np[] = "ncacn_np";
1756   static unsigned char pipe[] = PIPE;
1757   static unsigned char ncalrpc[] = "ncalrpc";
1758   static unsigned char guid[] = "00000000-4114-0704-2301-000000000000";
1759   RPC_STATUS status, iptcp_status, np_status, ncalrpc_status;
1760   DWORD ret;
1761 
1762   /* needed for tests involving interface pointers */
1763   CoInitializeEx(NULL, COINIT_MULTITHREADED);
1764 
1765   iptcp_status = RpcServerUseProtseqEpA(iptcp, 20, port, NULL);
1766   ok(iptcp_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_ip_tcp) failed with status %d\n", iptcp_status);
1767 
1768   ncalrpc_status = RpcServerUseProtseqEpA(ncalrpc, 0, guid, NULL);
1769   ok(ncalrpc_status == RPC_S_OK, "RpcServerUseProtseqEp(ncalrpc) failed with status %d\n", ncalrpc_status);
1770 
1771   np_status = RpcServerUseProtseqEpA(np, 0, pipe, NULL);
1772   if (np_status == RPC_S_PROTSEQ_NOT_SUPPORTED)
1773     skip("Protocol sequence ncacn_np is not supported\n");
1774   else
1775     ok(np_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", np_status);
1776 
1777   if (pRpcServerRegisterIfEx)
1778   {
1779     trace("Using RpcServerRegisterIfEx\n");
1780     status = pRpcServerRegisterIfEx(s_IServer_v0_0_s_ifspec, NULL, NULL,
1781                                     RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH,
1782                                     RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL);
1783   }
1784   else
1785     status = RpcServerRegisterIf(s_IServer_v0_0_s_ifspec, NULL, NULL);
1786   ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status);
1787   test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
1788   status = RpcServerListen(1, 20, TRUE);
1789   ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
1790   test_is_server_listening(NULL, RPC_S_OK);
1791   stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1792   ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError());
1793 
1794   if (iptcp_status == RPC_S_OK)
1795     run_client("tcp_basic");
1796   else
1797     skip("tcp tests skipped due to earlier failure\n");
1798 
1799   if (ncalrpc_status == RPC_S_OK)
1800   {
1801     run_client("ncalrpc_basic");
1802 
1803     /* we don't need to register RPC_C_AUTHN_WINNT for ncalrpc */
1804     run_client("ncalrpc_secure");
1805   }
1806   else
1807     skip("lrpc tests skipped due to earlier failure\n");
1808 
1809   if (np_status == RPC_S_OK)
1810     run_client("np_basic");
1811   else
1812   {
1813     skip("np_basic tests skipped due to earlier failure\n");
1814     /* np client is what signals stop_event, so bail out if we didn't run do it */
1815     return;
1816   }
1817 
1818   ret = WaitForSingleObject(stop_event, 1000);
1819   ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
1820   /* if the stop event didn't fire then RpcMgmtWaitServerListen will wait
1821    * forever, so don't bother calling it in this case */
1822   if (ret == WAIT_OBJECT_0)
1823   {
1824     status = RpcMgmtWaitServerListen();
1825     ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status);
1826   }
1827 
1828   CloseHandle(stop_event);
1829   stop_event = NULL;
1830 
1831   if (pRpcServerRegisterIfEx)
1832   {
1833     status = pRpcServerRegisterIfEx(s_IServer_v0_0_s_ifspec, NULL, NULL,
1834         RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH | RPC_IF_AUTOLISTEN,
1835         RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL);
1836     ok(status == RPC_S_OK, "RpcServerRegisterIf() failed: %u\n", status);
1837 
1838     run_client("ncalrpc_autolisten");
1839 
1840     status = RpcServerUnregisterIf(s_IServer_v0_0_s_ifspec, NULL, TRUE);
1841     ok(status == RPC_S_OK, "RpcServerUnregisterIf() failed: %u\n", status);
1842   }
1843 
1844   CoUninitialize();
1845 }
1846 
1847 static DWORD WINAPI listen_test_client_thread(void *binding)
1848 {
1849     RPC_STATUS status;
1850 
1851     status = RpcBindingFromStringBindingA(binding, &IServer_IfHandle);
1852     ok(status == RPC_S_OK, "RpcBindingFromStringBinding\n");
1853 
1854     test_is_server_listening(IServer_IfHandle, RPC_S_OK);
1855     stop();
1856     trace("stopped\n");
1857 
1858     status = RpcBindingFree(&IServer_IfHandle);
1859     ok(status == RPC_S_OK, "RpcBindingFree\n");
1860     return 0;
1861 }
1862 
1863 static DWORD WINAPI wait_listen_proc(void *arg)
1864 {
1865     RPC_STATUS status;
1866 
1867     trace("waiting\n");
1868     status = RpcMgmtWaitServerListen();
1869     ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status);
1870     trace("done\n");
1871 
1872     return 0;
1873 }
1874 
1875 static void test_stop_wait_for_call(unsigned char *binding)
1876 {
1877     HANDLE client_thread, wait_listen_thread;
1878     RPC_STATUS status;
1879     DWORD ret;
1880 
1881     status = RpcServerListen(1, 20, TRUE);
1882     ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
1883     test_is_server_listening(NULL, RPC_S_OK);
1884 
1885     stop_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1886     ok(stop_wait_event != NULL, "CreateEvent failed with error %d\n", GetLastError());
1887     stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1888     ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError());
1889 
1890     wait_listen_thread = CreateThread(NULL, 0, wait_listen_proc, 0, 0, NULL);
1891     ok(wait_listen_thread != NULL, "CreateThread failed\n");
1892 
1893     client_thread = CreateThread(NULL, 0, listen_test_client_thread, binding, 0, NULL);
1894     ok(client_thread != NULL, "CreateThread failed\n");
1895     CloseHandle(client_thread);
1896 
1897     ret = WaitForSingleObject(stop_event, 10000);
1898     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
1899 
1900     status = RpcMgmtStopServerListening(NULL);
1901     ok(status == RPC_S_OK, "RpcMgmtStopServerListening\n");
1902     test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
1903 
1904     ret = WaitForSingleObject(wait_listen_thread, 500);
1905     ok(WAIT_TIMEOUT == ret, "WaitForSingleObject\n");
1906 
1907     SetEvent(stop_wait_event);
1908 
1909     ret = WaitForSingleObject(wait_listen_thread, 10000);
1910     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject returned %u\n", ret);
1911 
1912     CloseHandle(wait_listen_thread);
1913 
1914     CloseHandle(stop_wait_event);
1915     stop_wait_event = NULL;
1916     CloseHandle(stop_event);
1917     stop_event = NULL;
1918 }
1919 
1920 static void test_server_listening(void)
1921 {
1922     static unsigned char np[] = "ncacn_np";
1923     static unsigned char address_np[] = "\\\\.";
1924     static unsigned char pipe[] = PIPE "listen_test";
1925     static unsigned char ncalrpc[] = "ncalrpc";
1926     static unsigned char guid[] = "00000000-4114-0704-2302-000000000000";
1927     unsigned char *binding;
1928     RPC_STATUS status;
1929 
1930     status = RpcServerUseProtseqEpA(np, 0, pipe, NULL);
1931     ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", status);
1932 
1933     status = RpcServerRegisterIf(s_IServer_v0_0_s_ifspec, NULL, NULL);
1934     ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status);
1935 
1936     test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
1937     status = RpcServerListen(1, 20, TRUE);
1938     ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
1939     test_is_server_listening(NULL, RPC_S_OK);
1940 
1941     status = RpcServerListen(1, 20, TRUE);
1942     ok(status == RPC_S_ALREADY_LISTENING, "RpcServerListen failed with status %d\n", status);
1943 
1944     status = RpcMgmtStopServerListening(NULL);
1945     ok(status == RPC_S_OK, "RpcMgmtStopServerListening\n");
1946     test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
1947 
1948     status = RpcMgmtWaitServerListen();
1949     ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status);
1950 
1951     status = RpcMgmtWaitServerListen();
1952     ok(status == RPC_S_NOT_LISTENING, "RpcMgmtWaitServerListening failed with status %d\n", status);
1953 
1954     /* test that server stop waits for a call in progress */
1955     status = RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding);
1956     ok(status == RPC_S_OK, "RpcStringBindingCompose\n");
1957 
1958     test_stop_wait_for_call(binding);
1959 
1960     status = RpcStringFreeA(&binding);
1961     ok(status == RPC_S_OK, "RpcStringFree\n");
1962 
1963     /* repeat the test using ncalrpc */
1964     status = RpcServerUseProtseqEpA(ncalrpc, 0, guid, NULL);
1965     ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncalrpc) failed with status %d\n", status);
1966 
1967     status = RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding);
1968     ok(status == RPC_S_OK, "RpcStringBindingCompose\n");
1969 
1970     test_stop_wait_for_call(binding);
1971 
1972     status = RpcStringFreeA(&binding);
1973     ok(status == RPC_S_OK, "RpcStringFree\n");
1974 }
1975 
1976 static HANDLE create_server_process(void)
1977 {
1978     SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE };
1979     HANDLE ready_event;
1980     char cmdline[MAX_PATH];
1981     PROCESS_INFORMATION info;
1982     STARTUPINFOA startup;
1983     DWORD ret;
1984 
1985     memset(&startup, 0, sizeof startup);
1986     startup.cb = sizeof startup;
1987 
1988     ready_event = CreateEventW(&sec_attr, TRUE, FALSE, NULL);
1989     ok(ready_event != NULL, "CreateEvent failed: %u\n", GetLastError());
1990 
1991     sprintf(cmdline, "%s server run %lx", progname, (UINT_PTR)ready_event);
1992     trace("running server process...\n");
1993     ok(CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
1994     ret = WaitForSingleObject(ready_event, 10000);
1995     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
1996 
1997     ok(CloseHandle(info.hThread), "CloseHandle\n");
1998     ok(CloseHandle(ready_event), "CloseHandle\n");
1999     return info.hProcess;
2000 }
2001 
2002 static void run_server(HANDLE ready_event)
2003 {
2004     static unsigned char np[] = "ncacn_np";
2005     static unsigned char pipe[] = PIPE "term_test";
2006     RPC_STATUS status;
2007     BOOL ret;
2008 
2009     status = RpcServerUseProtseqEpA(np, 0, pipe, NULL);
2010     ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", status);
2011 
2012     status = RpcServerRegisterIf(s_IServer_v0_0_s_ifspec, NULL, NULL);
2013     ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status);
2014 
2015     test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
2016     status = RpcServerListen(1, 20, TRUE);
2017     ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
2018 
2019     stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
2020     ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError());
2021 
2022     ret = SetEvent(ready_event);
2023     ok(ret, "SetEvent failed: %u\n", GetLastError());
2024 
2025     ret = WaitForSingleObject(stop_event, 1000);
2026     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
2027 
2028     status = RpcMgmtWaitServerListen();
2029     ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status);
2030 
2031     CloseHandle(stop_event);
2032     stop_event = NULL;
2033 }
2034 
2035 static DWORD WINAPI basic_tests_thread(void *arg)
2036 {
2037     basic_tests();
2038     return 0;
2039 }
2040 
2041 static void test_reconnect(void)
2042 {
2043     static unsigned char np[] = "ncacn_np";
2044     static unsigned char address_np[] = "\\\\.";
2045     static unsigned char pipe[] = PIPE "term_test";
2046     unsigned char *binding;
2047     HANDLE threads[32];
2048     HANDLE server_process;
2049     unsigned i;
2050     DWORD ret;
2051 
2052     server_process = create_server_process();
2053 
2054     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding), "RpcStringBindingCompose\n");
2055     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
2056 
2057     for (i = 0; i < ARRAY_SIZE(threads); i++)
2058     {
2059         threads[i] = CreateThread(NULL, 0, basic_tests_thread, 0, 0, NULL);
2060         ok(threads[i] != NULL, "CreateThread failed: %u\n", GetLastError());
2061     }
2062 
2063     for (i = 0; i < ARRAY_SIZE(threads); i++)
2064     {
2065         ret = WaitForSingleObject(threads[i], 10000);
2066         ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
2067         CloseHandle(threads[i]);
2068     }
2069 
2070     stop();
2071 
2072     winetest_wait_child_process(server_process);
2073     ok(CloseHandle(server_process), "CloseHandle\n");
2074 
2075     /* create new server, rpcrt4 will connect to it once sending to existing connection fails
2076      * that current connection is broken. */
2077     server_process = create_server_process();
2078     basic_tests();
2079     stop();
2080 
2081     winetest_wait_child_process(server_process);
2082     ok(CloseHandle(server_process), "CloseHandle\n");
2083 
2084     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
2085     ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n");
2086 }
2087 
2088 static BOOL is_process_elevated(void)
2089 {
2090     HANDLE token;
2091     if (OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token ))
2092     {
2093         TOKEN_ELEVATION_TYPE type;
2094         DWORD size;
2095         BOOL ret;
2096 
2097         ret = GetTokenInformation( token, TokenElevationType, &type, sizeof(type), &size );
2098         CloseHandle( token );
2099         return (ret && type == TokenElevationTypeFull);
2100     }
2101     return FALSE;
2102 }
2103 
2104 static BOOL is_firewall_enabled(void)
2105 {
2106     HRESULT hr, init;
2107     INetFwMgr *mgr = NULL;
2108     INetFwPolicy *policy = NULL;
2109     INetFwProfile *profile = NULL;
2110     VARIANT_BOOL enabled = VARIANT_FALSE;
2111 
2112     init = CoInitializeEx( 0, COINIT_APARTMENTTHREADED );
2113 
2114     hr = CoCreateInstance( &CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr,
2115                            (void **)&mgr );
2116     ok( hr == S_OK, "got %08x\n", hr );
2117     if (hr != S_OK) goto done;
2118 
2119     hr = INetFwMgr_get_LocalPolicy( mgr, &policy );
2120     ok( hr == S_OK, "got %08x\n", hr );
2121     if (hr != S_OK) goto done;
2122 
2123     hr = INetFwPolicy_get_CurrentProfile( policy, &profile );
2124     if (hr != S_OK) goto done;
2125 
2126     hr = INetFwProfile_get_FirewallEnabled( profile, &enabled );
2127     ok( hr == S_OK, "got %08x\n", hr );
2128 
2129 done:
2130     if (policy) INetFwPolicy_Release( policy );
2131     if (profile) INetFwProfile_Release( profile );
2132     if (mgr) INetFwMgr_Release( mgr );
2133     if (SUCCEEDED( init )) CoUninitialize();
2134     return (enabled == VARIANT_TRUE);
2135 }
2136 
2137 enum firewall_op
2138 {
2139     APP_ADD,
2140     APP_REMOVE
2141 };
2142 
2143 static HRESULT set_firewall( enum firewall_op op )
2144 {
2145     static const WCHAR testW[] = {'r','p','c','r','t','4','_','t','e','s','t',0};
2146     HRESULT hr, init;
2147     INetFwMgr *mgr = NULL;
2148     INetFwPolicy *policy = NULL;
2149     INetFwProfile *profile = NULL;
2150     INetFwAuthorizedApplication *app = NULL;
2151     INetFwAuthorizedApplications *apps = NULL;
2152     BSTR name, image = SysAllocStringLen( NULL, MAX_PATH );
2153 
2154     if (!GetModuleFileNameW( NULL, image, MAX_PATH ))
2155     {
2156         SysFreeString( image );
2157         return E_FAIL;
2158     }
2159     init = CoInitializeEx( 0, COINIT_APARTMENTTHREADED );
2160 
2161     hr = CoCreateInstance( &CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr,
2162                            (void **)&mgr );
2163     ok( hr == S_OK, "got %08x\n", hr );
2164     if (hr != S_OK) goto done;
2165 
2166     hr = INetFwMgr_get_LocalPolicy( mgr, &policy );
2167     ok( hr == S_OK, "got %08x\n", hr );
2168     if (hr != S_OK) goto done;
2169 
2170     hr = INetFwPolicy_get_CurrentProfile( policy, &profile );
2171     if (hr != S_OK) goto done;
2172 
2173     hr = INetFwProfile_get_AuthorizedApplications( profile, &apps );
2174     ok( hr == S_OK, "got %08x\n", hr );
2175     if (hr != S_OK) goto done;
2176 
2177     hr = CoCreateInstance( &CLSID_NetFwAuthorizedApplication, NULL, CLSCTX_INPROC_SERVER,
2178                            &IID_INetFwAuthorizedApplication, (void **)&app );
2179     ok( hr == S_OK, "got %08x\n", hr );
2180     if (hr != S_OK) goto done;
2181 
2182     hr = INetFwAuthorizedApplication_put_ProcessImageFileName( app, image );
2183     if (hr != S_OK) goto done;
2184 
2185     name = SysAllocString( testW );
2186     hr = INetFwAuthorizedApplication_put_Name( app, name );
2187     SysFreeString( name );
2188     ok( hr == S_OK, "got %08x\n", hr );
2189     if (hr != S_OK) goto done;
2190 
2191     if (op == APP_ADD)
2192         hr = INetFwAuthorizedApplications_Add( apps, app );
2193     else if (op == APP_REMOVE)
2194         hr = INetFwAuthorizedApplications_Remove( apps, image );
2195     else
2196         hr = E_INVALIDARG;
2197 
2198 done:
2199     if (app) INetFwAuthorizedApplication_Release( app );
2200     if (apps) INetFwAuthorizedApplications_Release( apps );
2201     if (policy) INetFwPolicy_Release( policy );
2202     if (profile) INetFwProfile_Release( profile );
2203     if (mgr) INetFwMgr_Release( mgr );
2204     if (SUCCEEDED( init )) CoUninitialize();
2205     SysFreeString( image );
2206     return hr;
2207 }
2208 
2209 START_TEST(server)
2210 {
2211   ULONG size = 0;
2212   int argc;
2213   char **argv;
2214   BOOL firewall_enabled = is_firewall_enabled(), firewall_disabled = FALSE;
2215 
2216   InitFunctionPointers();
2217 
2218   ok(!GetUserNameExA(NameSamCompatible, NULL, &size), "GetUserNameExA\n");
2219   domain_and_user = HeapAlloc(GetProcessHeap(), 0, size);
2220   ok(GetUserNameExA(NameSamCompatible, domain_and_user, &size), "GetUserNameExA\n");
2221 
2222   argc = winetest_get_mainargs(&argv);
2223   progname = argv[0];
2224 
2225   if (argc == 3)
2226   {
2227     RpcTryExcept
2228     {
2229       client(argv[2]);
2230     }
2231     RpcExcept(TRUE)
2232     {
2233       trace("Exception %d\n", RpcExceptionCode());
2234     }
2235     RpcEndExcept
2236   }
2237   else if (argc == 4)
2238   {
2239     if (!strcmp(argv[3], "listen"))
2240     {
2241       test_server_listening();
2242     }
2243     else if(!strcmp(argv[2], "run"))
2244     {
2245       UINT_PTR event;
2246       sscanf(argv[3], "%lx", &event);
2247       run_server((HANDLE)event);
2248     }
2249   }
2250   else
2251   {
2252     if (firewall_enabled)
2253     {
2254       if (is_process_elevated())
2255       {
2256         HRESULT hr = set_firewall(APP_ADD);
2257         if (hr == S_OK)
2258         {
2259           firewall_enabled = FALSE;
2260           firewall_disabled = TRUE;
2261         }
2262         else
2263         {
2264           skip("can't authorize app in firewall %08x\n", hr);
2265         }
2266       }
2267       else
2268       {
2269           trace("no privileges, skipping tests to avoid firewall dialog\n");
2270       }
2271     }
2272 
2273     if (!firewall_enabled) server();
2274 
2275     /* Those tests cause occasional crashes on winxp and win2k3 */
2276     if (GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "RpcExceptionFilter"))
2277         test_reconnect();
2278     else
2279         win_skip("Skipping reconnect tests on too old Windows version\n");
2280 
2281     run_client("test listen");
2282     if (firewall_disabled) set_firewall(APP_REMOVE);
2283   }
2284 
2285   HeapFree(GetProcessHeap(), 0, domain_and_user);
2286 }
2287