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