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 
set_interp_interface(void)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 
set_mixed_interface(void)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 
InitFunctionPointers(void)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
midl_user_allocate(SIZE_T n)279 midl_user_allocate(SIZE_T n)
280 {
281   return HeapAlloc(GetProcessHeap(), 0, n);
282 }
283 
284 void __RPC_USER
midl_user_free(void __RPC_FAR * p)285 midl_user_free(void __RPC_FAR *p)
286 {
287   HeapFree(GetProcessHeap(), 0, p);
288 }
289 
290 static char *
xstrdup(const char * s)291 xstrdup(const char *s)
292 {
293   char *d = HeapAlloc(GetProcessHeap(), 0, strlen(s) + 1);
294   strcpy(d, s);
295   return d;
296 }
297 
s_int_return(void)298 int __cdecl s_int_return(void)
299 {
300   return INT_CODE;
301 }
302 
s_square(int x)303 int __cdecl s_square(int x)
304 {
305   return x * x;
306 }
307 
s_sum(int x,int y)308 int __cdecl s_sum(int x, int y)
309 {
310   return x + y;
311 }
312 
s_sum_char(signed char x,signed char y)313 signed char __cdecl s_sum_char(signed char x, signed char y)
314 {
315     return x + y;
316 }
317 
s_sum_short(short x,short y)318 short __cdecl s_sum_short(short x, short y)
319 {
320     return x + y;
321 }
322 
s_sum_float(float x,float y)323 int __cdecl s_sum_float(float x, float y)
324 {
325     return x + y;
326 }
327 
s_sum_double_int(int x,double y)328 int __cdecl s_sum_double_int(int x, double y)
329 {
330     return x + y;
331 }
332 
s_sum_hyper(hyper x,hyper y)333 hyper __cdecl s_sum_hyper(hyper x, hyper y)
334 {
335     return x + y;
336 }
337 
s_sum_hyper_int(hyper x,hyper y)338 int __cdecl s_sum_hyper_int(hyper x, hyper y)
339 {
340     return x + y;
341 }
342 
s_sum_char_hyper(signed char x,hyper y)343 int __cdecl s_sum_char_hyper(signed char x, hyper y)
344 {
345     return x + y;
346 }
347 
s_square_out(int x,int * y)348 void __cdecl s_square_out(int x, int *y)
349 {
350   *y = s_square(x);
351 }
352 
s_square_ref(int * x)353 void __cdecl s_square_ref(int *x)
354 {
355   *x = s_square(*x);
356 }
357 
s_str_length(const char * s)358 int __cdecl s_str_length(const char *s)
359 {
360   return strlen(s);
361 }
362 
s_str_t_length(str_t s)363 int __cdecl s_str_t_length(str_t s)
364 {
365   return strlen(s);
366 }
367 
s_cstr_length(const char * s,int n)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 
s_dot_self(vector_t * v)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 
s_square_half(double x,double * y)381 double __cdecl s_square_half(double x, double *y)
382 {
383   *y = x / 2.0;
384   return x * x;
385 }
386 
s_square_half_float(float x,float * y)387 float __cdecl s_square_half_float(float x, float *y)
388 {
389   *y = x / 2.0f;
390   return x * x;
391 }
392 
s_square_half_long(LONG x,LONG * y)393 LONG __cdecl s_square_half_long(LONG x, LONG *y)
394 {
395   *y = x / 2;
396   return x * x;
397 }
398 
s_sum_fixed_array(int a[5])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 
s_pints_sum(pints_t * pints)404 int __cdecl s_pints_sum(pints_t *pints)
405 {
406   return *pints->pi + **pints->ppi + ***pints->pppi;
407 }
408 
s_ptypes_sum(ptypes_t * pt)409 double __cdecl s_ptypes_sum(ptypes_t *pt)
410 {
411   return *pt->pc + *pt->ps + *pt->pl + *pt->pf + *pt->pd;
412 }
413 
s_dot_pvectors(pvectors_t * p)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 
s_sum_sp(sp_t * sp)419 int __cdecl s_sum_sp(sp_t *sp)
420 {
421   return sp->x + sp->s->x;
422 }
423 
s_square_sun(sun_t * su)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 
s_test_list_length(test_list_t * list)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 
s_sum_fixed_int_3d(int m[2][3][4])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 
s_sum_conf_array(int x[],int n)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 
s_sum_conf_ptr_by_conf_ptr(int n1,int * n2_then_x1,int * x2)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 
s_sum_unique_conf_array(int x[],int n)484 int __cdecl s_sum_unique_conf_array(int x[], int n)
485 {
486   return s_sum_conf_array(x, n);
487 }
488 
s_sum_unique_conf_ptr(int * x,int n)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 
s_sum_var_array(int x[20],int n)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 
s_sum_complex_array(int n,refpint_t pi[])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 
s_dot_two_vectors(vector_t vs[2])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 
s_get_number_array(int x[20],int * n)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 
s_sum_cs(cs_t * cs)522 int __cdecl s_sum_cs(cs_t *cs)
523 {
524   return s_sum_conf_array(cs->ca, cs->n);
525 }
526 
s_sum_cps(cps_t * cps)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 
s_sum_cpsc(cpsc_t * cpsc)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 
s_get_cpsc(int n,cpsc_t * cpsc)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 
s_square_puint(puint_t p)563 int __cdecl s_square_puint(puint_t p)
564 {
565   int n = atoi(p);
566   return n * n;
567 }
568 
s_sum_puints(puints_t * p)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 
s_sum_cpuints(cpuints_t * p)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 
s_dot_copy_vectors(vector_t u,vector_t v)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 
s_square_test_us(test_us_t * tus)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 
s_square_encu(encu_t * eu)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 
s_square_unencu(int t,unencu_t * eu)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 
s_check_se2(se_t * s)620 void __cdecl s_check_se2(se_t *s)
621 {
622   ok(s->f == E2, "check_se2\n");
623 }
624 
s_sum_parr(int * a[3])625 int __cdecl s_sum_parr(int *a[3])
626 {
627   return s_sum_pcarr(a, 3);
628 }
629 
s_sum_pcarr(int * a[],int n)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 
s_enum_ord(e_t e)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 
s_square_encue(encue_t * eue)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 
s_sum_toplev_conf_2n(int * x,int n)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 
s_sum_toplev_conf_cond(int * x,int a,int b,int c)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 
s_sum_aligns(aligns_t * a)681 double __cdecl s_sum_aligns(aligns_t *a)
682 {
683   return a->c + a->i + a->s + a->d;
684 }
685 
s_sum_padded(padded_t * p)686 int __cdecl s_sum_padded(padded_t *p)
687 {
688   return p->i + p->c;
689 }
690 
s_sum_padded2(padded_t ps[2])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 
s_sum_padded_conf(padded_t * ps,int n)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 
s_sum_bogus(bogus_t * b)705 int __cdecl s_sum_bogus(bogus_t *b)
706 {
707   return *b->h.p1 + *b->p2 + *b->p3 + b->c;
708 }
709 
s_check_null(int * null)710 void __cdecl s_check_null(int *null)
711 {
712   ok(!null, "RPC check_null\n");
713 }
714 
s_str_struct_len(str_struct_t * s)715 int __cdecl s_str_struct_len(str_struct_t *s)
716 {
717   return lstrlenA(s->s);
718 }
719 
s_wstr_struct_len(wstr_struct_t * s)720 int __cdecl s_wstr_struct_len(wstr_struct_t *s)
721 {
722   return lstrlenW(s->s);
723 }
724 
s_sum_doub_carr(doub_carr_t * dc)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 
s_make_pyramid_doub_carr(unsigned char n,doub_carr_t ** dc)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 
s_hash_bstr(bstr_t b)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 
s_get_a_bstr(bstr_t * b)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 
s_get_name(name_t * name)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 
s_get_names(int * n,str_array_t * names)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 
s_get_namesw(int * n,wstr_array_t * names)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 
s_sum_pcarr2(int n,int ** pa)809 int __cdecl s_sum_pcarr2(int n, int **pa)
810 {
811   return s_sum_conf_array(*pa, n);
812 }
813 
s_sum_L1_norms(int n,vector_t * vs)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 
s_get_s123(void)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 
s_get_filename(void)832 str_t __cdecl s_get_filename(void)
833 {
834     return (char *)__FILE__;
835 }
836 
s_echo_ranged_int(int i,int j,int k)837 int __cdecl s_echo_ranged_int(int i, int j, int k)
838 {
839     return min( 100, i + j + k );
840 }
841 
s_echo_ranged_int2(int i)842 int __cdecl s_echo_ranged_int2(int i)
843 {
844     return i;
845 }
846 
s_get_ranged_enum(renum_t * re)847 void __cdecl s_get_ranged_enum(renum_t *re)
848 {
849     *re = RE3;
850 }
851 
s_context_handle_test(void)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 
s_get_numbers(int length,int size,pints_t n[])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 
s_get_numbers_struct(numbers_struct_t ** ns)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 
s_full_pointer_test(int * a,int * b)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 
s_full_pointer_null_test(int * a,int * b)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 
s_stop(void)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 
s_stop_autolisten(void)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 
s_ip_test(ipu_t * a)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 
s_sum_ptr_array(int * a[2])1067 int __cdecl s_sum_ptr_array(int *a[2])
1068 {
1069     return *a[0] + *a[1];
1070 }
1071 
s_sum_array_ptr(int (* a)[2])1072 int __cdecl s_sum_array_ptr(int (*a)[2])
1073 {
1074     return (*a)[0] + (*a)[1];
1075 }
1076 
s_get_handle(void)1077 ctx_handle_t __cdecl s_get_handle(void)
1078 {
1079     return (ctx_handle_t)0xdeadbeef;
1080 }
1081 
s_get_handle_by_ptr(ctx_handle_t * r)1082 void __cdecl s_get_handle_by_ptr(ctx_handle_t *r)
1083 {
1084     *r = (ctx_handle_t)0xdeadbeef;
1085 }
1086 
s_test_handle(ctx_handle_t ctx_handle)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 
ctx_handle_t_rundown(ctx_handle_t ctx_handle)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
make_cmdline(char buffer[MAX_PATH],const char * test)1098 make_cmdline(char buffer[MAX_PATH], const char *test)
1099 {
1100   sprintf(buffer, "%s server %s", progname, test);
1101 }
1102 
1103 static void
run_client(const char * test)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
basic_tests(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
union_tests(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 *
null_list(void)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 *
make_list(test_list_t * tail)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
free_list(test_list_t * list)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
puint_t_UserSize(ULONG * flags,ULONG start,puint_t * p)1379 puint_t_UserSize(ULONG *flags, ULONG start, puint_t *p)
1380 {
1381   return start + sizeof(int);
1382 }
1383 
1384 unsigned char * __RPC_USER
puint_t_UserMarshal(ULONG * flags,unsigned char * buffer,puint_t * p)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
puint_t_UserUnmarshal(ULONG * flags,unsigned char * buffer,puint_t * p)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
puint_t_UserFree(ULONG * flags,puint_t * p)1403 puint_t_UserFree(ULONG *flags, puint_t *p)
1404 {
1405   HeapFree(GetProcessHeap(), 0, *p);
1406 }
1407 
1408 ULONG __RPC_USER
us_t_UserSize(ULONG * flags,ULONG start,us_t * pus)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
us_t_UserMarshal(ULONG * flags,unsigned char * buffer,us_t * pus)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
us_t_UserUnmarshal(ULONG * flags,unsigned char * buffer,us_t * pus)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
us_t_UserFree(ULONG * flags,us_t * pus)1434 us_t_UserFree(ULONG *flags, us_t *pus)
1435 {
1436   HeapFree(GetProcessHeap(), 0, pus->x);
1437 }
1438 
1439 ULONG __RPC_USER
bstr_t_UserSize(ULONG * flags,ULONG start,bstr_t * b)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
bstr_t_UserMarshal(ULONG * flags,unsigned char * buffer,bstr_t * b)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
bstr_t_UserUnmarshal(ULONG * flags,unsigned char * buffer,bstr_t * b)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
bstr_t_UserFree(ULONG * flags,bstr_t * b)1466 bstr_t_UserFree(ULONG *flags, bstr_t *b)
1467 {
1468   HeapFree(GetProcessHeap(), 0, &((*b)[-1]));
1469 }
1470 
1471 static void
pointer_tests(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       ros_skip_flaky
1557       ok(!strcmp(names[0], "Hello"), "expected Hello, got %s\n", names[0]);
1558       ros_skip_flaky
1559       ok(!strcmp(names[1], "World!"), "expected World!, got %s\n", names[1]);
1560       MIDL_user_free(names[0]);
1561       MIDL_user_free(names[1]);
1562       MIDL_user_free(names);
1563 
1564       n = -1;
1565       namesw = NULL;
1566       get_namesw(&n, &namesw);
1567       ok(n == 2, "expected 2, got %d\n", n);
1568       ros_skip_flaky
1569       ok(!lstrcmpW(namesw[0], helloW), "expected Hello, got %s\n", wine_dbgstr_w(namesw[0]));
1570       ros_skip_flaky
1571       ok(!lstrcmpW(namesw[1], worldW), "expected World!, got %s\n", wine_dbgstr_w(namesw[1]));
1572       MIDL_user_free(namesw[0]);
1573       MIDL_user_free(namesw[1]);
1574       MIDL_user_free(namesw);
1575       }
1576   }
1577 
1578   if (!is_interp) { /* broken in widl */
1579   pa2 = a;
1580   ros_skip_flaky
1581   ok(sum_pcarr2(4, &pa2) == 10, "RPC sum_pcarr2\n");
1582   }
1583 
1584   s123 = get_s123();
1585   ok(s123->f1 == 1 && s123->f2 == 2 && s123->f3 == 3, "RPC get_s123\n");
1586   MIDL_user_free(s123);
1587 
1588   full_pointer_test(&val, &val);
1589   full_pointer_null_test(&val, NULL);
1590 }
1591 
1592 static int
check_pyramid_doub_carr(doub_carr_t * dc)1593 check_pyramid_doub_carr(doub_carr_t *dc)
1594 {
1595   int i, j;
1596   for (i = 0; i < dc->n; ++i)
1597     for (j = 0; j < dc->a[i]->n; ++j)
1598       if (dc->a[i]->a[j] != j + 1)
1599         return FALSE;
1600   return TRUE;
1601 }
1602 
1603 static void
free_pyramid_doub_carr(doub_carr_t * dc)1604 free_pyramid_doub_carr(doub_carr_t *dc)
1605 {
1606   int i;
1607   for (i = 0; i < dc->n; ++i)
1608     MIDL_user_free(dc->a[i]);
1609   MIDL_user_free(dc);
1610 }
1611 
1612 static void
array_tests(void)1613 array_tests(void)
1614 {
1615   int m[2][3][4] =
1616   {
1617     {{1, 2, 3, 4}, {-1, -3, -5, -7}, {0, 2, 4, 6}},
1618     {{1, -2, 3, -4}, {2, 3, 5, 7}, {-4, -1, -14, 4114}}
1619   };
1620   int c[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1621   int c2[] = {10, 100, 200};
1622   int c3[20];
1623   vector_t vs[2] = {{1, -2, 3}, {4, -5, -6}};
1624   cps_t cps;
1625   cpsc_t cpsc;
1626   cs_t *cs;
1627   int n;
1628   int ca[5] = {1, -2, 3, -4, 5};
1629   int tmp[10];
1630   doub_carr_t *dc;
1631   int *pi;
1632   pints_t api[5];
1633   numbers_struct_t *ns;
1634   refpint_t rpi[5];
1635   int i0 = 1, i1 = 2, *ptr_array[2] = {&i0, &i1}, array[2] = {3, 4};
1636 
1637   if (!old_windows_version)
1638   {
1639       const char str1[25] = "Hello";
1640       ok(cstr_length(str1, sizeof str1) == strlen(str1), "RPC cstr_length\n");
1641   }
1642 
1643   ok(sum_fixed_int_3d(m) == 4116, "RPC sum_fixed_int_3d\n");
1644 
1645   ok(sum_conf_array(c, 10) == 45, "RPC sum_conf_array\n");
1646   ok(sum_conf_array(&c[5], 2) == 11, "RPC sum_conf_array\n");
1647   ok(sum_conf_array(&c[7], 1) == 7, "RPC sum_conf_array\n");
1648   ok(sum_conf_array(&c[2], 0) == 0, "RPC sum_conf_array\n");
1649 
1650   ok(sum_conf_ptr_by_conf_ptr(1, c2, c) == 45, "RPC sum_conf_ptr_by_conf_ptr\n");
1651   ok(sum_conf_ptr_by_conf_ptr(3, c2, c) == 345, "RPC sum_conf_ptr_by_conf_ptr\n");
1652   c2[0] = 0;
1653   ok(sum_conf_ptr_by_conf_ptr(3, c2, c) == 300, "RPC sum_conf_ptr_by_conf_ptr\n");
1654 
1655   ok(sum_unique_conf_array(ca, 4) == -2, "RPC sum_unique_conf_array\n");
1656   ok(sum_unique_conf_ptr(ca, 5) == 3, "RPC sum_unique_conf_array\n");
1657   ok(sum_unique_conf_ptr(NULL, 10) == 0, "RPC sum_unique_conf_array\n");
1658 
1659   get_number_array(c3, &n);
1660   ok(n == 10, "RPC get_num_array\n");
1661   for (; n > 0; n--)
1662     ok(c3[n-1] == c[n-1], "get_num_array returned wrong value %d @ %d\n",
1663        c3[n-1], n);
1664   ok(sum_var_array(c, 10) == 45, "RPC sum_conf_array\n");
1665   ok(sum_var_array(&c[5], 2) == 11, "RPC sum_conf_array\n");
1666   ok(sum_var_array(&c[7], 1) == 7, "RPC sum_conf_array\n");
1667   ok(sum_var_array(&c[2], 0) == 0, "RPC sum_conf_array\n");
1668 
1669   ok(dot_two_vectors(vs) == -4, "RPC dot_two_vectors\n");
1670   cs = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(cs_t, ca[5]));
1671   cs->n = 5;
1672   cs->ca[0] = 3;
1673   cs->ca[1] = 5;
1674   cs->ca[2] = -2;
1675   cs->ca[3] = -1;
1676   cs->ca[4] = -4;
1677   ok(sum_cs(cs) == 1, "RPC sum_cs\n");
1678   HeapFree(GetProcessHeap(), 0, cs);
1679 
1680   n = 5;
1681   cps.pn = &n;
1682   cps.ca1 = &c[2];
1683   cps.n = 3;
1684   cps.ca2 = &c[3];
1685   ok(sum_cps(&cps) == 53, "RPC sum_cps\n");
1686 
1687   cpsc.a = 4;
1688   cpsc.b = 5;
1689   cpsc.c = 1;
1690   cpsc.ca = c;
1691   ok(sum_cpsc(&cpsc) == 6, "RPC sum_cpsc\n");
1692   cpsc.a = 4;
1693   cpsc.b = 5;
1694   cpsc.c = 0;
1695   cpsc.ca = c;
1696   ok(sum_cpsc(&cpsc) == 10, "RPC sum_cpsc\n");
1697 
1698   cpsc.ca = NULL;
1699   ok(get_cpsc(5, &cpsc) == 45, "RPC sum_cpsc\n");
1700   ok( cpsc.a == 10, "RPC get_cpsc %u\n", cpsc.a );
1701   for (n = 0; n < 10; n++) ok( cpsc.ca[n] == n, "RPC get_cpsc[%d] = %d\n", n, cpsc.ca[n] );
1702 
1703   memset( tmp, 0x33, sizeof(tmp) );
1704   cpsc.ca = tmp;
1705   ok(get_cpsc(4, &cpsc) == 28, "RPC sum_cpsc\n");
1706   ok( cpsc.a == 8, "RPC get_cpsc %u\n", cpsc.a );
1707   ok( cpsc.ca == tmp, "RPC get_cpsc %p/%p\n", cpsc.ca, tmp );
1708   for (n = 0; n < 8; n++) ok( cpsc.ca[n] == n, "RPC get_cpsc[%d] = %d\n", n, cpsc.ca[n] );
1709 
1710   ok(sum_toplev_conf_2n(c, 3) == 15, "RPC sum_toplev_conf_2n\n");
1711   ok(sum_toplev_conf_cond(c, 5, 6, 1) == 10, "RPC sum_toplev_conf_cond\n");
1712   ok(sum_toplev_conf_cond(c, 5, 6, 0) == 15, "RPC sum_toplev_conf_cond\n");
1713 
1714   dc = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(doub_carr_t, a[2]));
1715   dc->n = 2;
1716   dc->a[0] = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(doub_carr_1_t, a[3]));
1717   dc->a[0]->n = 3;
1718   dc->a[0]->a[0] = 5;
1719   dc->a[0]->a[1] = 1;
1720   dc->a[0]->a[2] = 8;
1721   dc->a[1] = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(doub_carr_1_t, a[2]));
1722   dc->a[1]->n = 2;
1723   dc->a[1]->a[0] = 2;
1724   dc->a[1]->a[1] = 3;
1725   ok(sum_doub_carr(dc) == 19, "RPC sum_doub_carr\n");
1726   HeapFree(GetProcessHeap(), 0, dc->a[0]);
1727   HeapFree(GetProcessHeap(), 0, dc->a[1]);
1728   HeapFree(GetProcessHeap(), 0, dc);
1729 
1730   dc = NULL;
1731   make_pyramid_doub_carr(4, &dc);
1732   ok(check_pyramid_doub_carr(dc), "RPC make_pyramid_doub_carr\n");
1733   free_pyramid_doub_carr(dc);
1734 
1735   ok(sum_L1_norms(2, vs) == 21, "RPC sum_L1_norms\n");
1736 
1737   memset(api, 0, sizeof(api));
1738   pi = HeapAlloc(GetProcessHeap(), 0, sizeof(*pi));
1739   *pi = -1;
1740   api[0].pi = pi;
1741   get_numbers(1, 1, api);
1742   ok(api[0].pi == pi, "RPC conformant varying array [out] pointer changed from %p to %p\n", pi, api[0].pi);
1743   ok(*api[0].pi == 0, "pi unmarshalled incorrectly %d\n", *api[0].pi);
1744 
1745   if (!old_windows_version)
1746   {
1747       ns = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(numbers_struct_t, numbers[5]));
1748       ns->length = 5;
1749       ns->size = 5;
1750       ns->numbers[0].pi = pi;
1751       get_numbers_struct(&ns);
1752       ok(ns->numbers[0].pi == pi, "RPC conformant varying struct embedded pointer changed from %p to %p\n", pi, ns->numbers[0].pi);
1753       ok(*ns->numbers[0].pi == 5, "pi unmarshalled incorrectly %d\n", *ns->numbers[0].pi);
1754       HeapFree(GetProcessHeap(), 0, ns);
1755   }
1756   HeapFree(GetProcessHeap(), 0, pi);
1757 
1758   pi = HeapAlloc(GetProcessHeap(), 0, 5 * sizeof(*pi));
1759   pi[0] = 3;  rpi[0] = &pi[0];
1760   pi[1] = 5;  rpi[1] = &pi[1];
1761   pi[2] = -2; rpi[2] = &pi[2];
1762   pi[3] = -1; rpi[3] = &pi[3];
1763   pi[4] = -4; rpi[4] = &pi[4];
1764   ok(sum_complex_array(5, rpi) == 1, "RPC sum_complex_array\n");
1765   HeapFree(GetProcessHeap(), 0, pi);
1766 
1767   ok(sum_ptr_array(ptr_array) == 3, "RPC sum_ptr_array\n");
1768   ok(sum_array_ptr(&array) == 7, "RPC sum_array_ptr\n");
1769 }
1770 
s_authinfo_test(unsigned int protseq,int secure)1771 void __cdecl s_authinfo_test(unsigned int protseq, int secure)
1772 {
1773     RPC_BINDING_HANDLE binding;
1774     RPC_STATUS status;
1775     ULONG level, authnsvc;
1776     RPC_AUTHZ_HANDLE privs;
1777     unsigned char *principal;
1778 
1779     binding = I_RpcGetCurrentCallHandle();
1780     ok(binding != NULL, "I_RpcGetCurrentCallHandle returned NULL\n");
1781 
1782     level = authnsvc = 0xdeadbeef;
1783     privs = (RPC_AUTHZ_HANDLE)0xdeadbeef;
1784     principal = (unsigned char *)0xdeadbeef;
1785 
1786     if (secure || protseq == RPC_PROTSEQ_LRPC)
1787     {
1788         status = RpcBindingInqAuthClientA(binding, &privs, &principal, &level, &authnsvc, NULL);
1789         if (status == RPC_S_CANNOT_SUPPORT)
1790         {
1791             win_skip("RpcBindingInqAuthClientA not supported\n");
1792             return;
1793         }
1794         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1795         ok(privs != (RPC_AUTHZ_HANDLE)0xdeadbeef, "privs unchanged\n");
1796         ok(principal != (unsigned char *)0xdeadbeef, "principal unchanged\n");
1797         if (protseq != RPC_PROTSEQ_LRPC)
1798         {
1799             todo_wine
1800             ok(principal != NULL, "NULL principal\n");
1801         }
1802         if (protseq == RPC_PROTSEQ_LRPC && principal)
1803         {
1804             int len;
1805             char *spn;
1806 
1807             len = WideCharToMultiByte(CP_ACP, 0, (const WCHAR *)privs, -1, NULL, 0, NULL, NULL);
1808             spn = HeapAlloc( GetProcessHeap(), 0, len );
1809             WideCharToMultiByte(CP_ACP, 0, (const WCHAR *)privs, -1, spn, len, NULL, NULL);
1810 
1811             ok(!strcmp(domain_and_user, spn), "expected %s got %s\n", domain_and_user, spn);
1812             HeapFree( GetProcessHeap(), 0, spn );
1813         }
1814         ok(level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY, "level unchanged\n");
1815         ok(authnsvc == RPC_C_AUTHN_WINNT, "authnsvc unchanged\n");
1816         RpcStringFreeA(&principal);
1817 
1818         status = RpcBindingInqAuthClientA(NULL, &privs, &principal, &level, &authnsvc, NULL);
1819         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1820         RpcStringFreeA(&principal);
1821 
1822         status = RpcBindingInqAuthClientExA(NULL, &privs, &principal, &level, &authnsvc, NULL, 0);
1823         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1824         RpcStringFreeA(&principal);
1825 
1826         status = RpcImpersonateClient(NULL);
1827         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1828         status = RpcRevertToSelf();
1829         ok(status == RPC_S_OK, "expected RPC_S_OK got %u\n", status);
1830 
1831     }
1832     else
1833     {
1834         status = RpcBindingInqAuthClientA(binding, &privs, &principal, &level, &authnsvc, NULL);
1835         ok(status == RPC_S_BINDING_HAS_NO_AUTH, "expected RPC_S_BINDING_HAS_NO_AUTH got %u\n", status);
1836         ok(privs == (RPC_AUTHZ_HANDLE)0xdeadbeef, "got %p\n", privs);
1837         ok(principal == (unsigned char *)0xdeadbeef, "got %s\n", principal);
1838         ok(level == 0xdeadbeef, "got %u\n", level);
1839         ok(authnsvc == 0xdeadbeef, "got %u\n", authnsvc);
1840     }
1841 }
1842 
test_handle_return(void)1843 static void test_handle_return(void)
1844 {
1845     ctx_handle_t handle, handle2;
1846 
1847     handle = get_handle();
1848     test_handle(handle);
1849     get_handle_by_ptr(&handle2);
1850     test_handle(handle2);
1851 }
1852 
1853 static void
run_tests(void)1854 run_tests(void)
1855 {
1856   basic_tests();
1857   union_tests();
1858   pointer_tests();
1859   array_tests();
1860   context_handle_test();
1861   test_handle_return();
1862 }
1863 
1864 static void
set_auth_info(RPC_BINDING_HANDLE handle)1865 set_auth_info(RPC_BINDING_HANDLE handle)
1866 {
1867     RPC_STATUS status;
1868     RPC_SECURITY_QOS qos;
1869 
1870     qos.Version = 1;
1871     qos.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH;
1872     qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
1873     qos.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
1874 
1875     status = pRpcBindingSetAuthInfoExA(handle, (RPC_CSTR)domain_and_user, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
1876                                        RPC_C_AUTHN_WINNT, NULL, 0, &qos);
1877     ok(status == RPC_S_OK, "RpcBindingSetAuthInfoExA failed %d\n", status);
1878 }
1879 
1880 #define test_is_server_listening(a,b) _test_is_server_listening(__LINE__,a,b)
_test_is_server_listening(unsigned line,RPC_BINDING_HANDLE binding,RPC_STATUS expected_status)1881 static void _test_is_server_listening(unsigned line, RPC_BINDING_HANDLE binding, RPC_STATUS expected_status)
1882 {
1883     RPC_STATUS status;
1884     status = RpcMgmtIsServerListening(binding);
1885     ok_(__FILE__,line)(status == expected_status, "RpcMgmtIsServerListening returned %u, expected %u\n",
1886                        status, expected_status);
1887 }
1888 
1889 #define test_is_server_listening2(a,b,c) _test_is_server_listening2(__LINE__,a,b,c)
_test_is_server_listening2(unsigned line,RPC_BINDING_HANDLE binding,RPC_STATUS expected_status,RPC_STATUS expected_status2)1890 static void _test_is_server_listening2(unsigned line, RPC_BINDING_HANDLE binding, RPC_STATUS expected_status,
1891         RPC_STATUS expected_status2)
1892 {
1893     RPC_STATUS status;
1894     status = RpcMgmtIsServerListening(binding);
1895     ok_(__FILE__,line)(status == expected_status || status == expected_status2,
1896                        "RpcMgmtIsServerListening returned %u, expected %u or %u\n",
1897                        status, expected_status, expected_status2);
1898 }
1899 
1900 static void
client(const char * test)1901 client(const char *test)
1902 {
1903   static unsigned char iptcp[] = "ncacn_ip_tcp";
1904   static unsigned char np[] = "ncacn_np";
1905   static unsigned char ncalrpc[] = "ncalrpc";
1906   static unsigned char address[] = "127.0.0.1";
1907   static unsigned char address_np[] = "\\\\.";
1908   static unsigned char port[] = PORT;
1909   static unsigned char pipe[] = PIPE;
1910   static unsigned char guid[] = "00000000-4114-0704-2301-000000000000";
1911 
1912   unsigned char *binding;
1913 
1914   if (strcmp(test, "tcp_basic") == 0)
1915   {
1916     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, iptcp, address, port, NULL, &binding), "RpcStringBindingCompose\n");
1917     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle), "RpcBindingFromStringBinding\n");
1918 
1919     run_tests();
1920     authinfo_test(RPC_PROTSEQ_TCP, 0);
1921     test_is_server_listening2(IMixedServer_IfHandle, RPC_S_OK, RPC_S_ACCESS_DENIED);
1922 
1923     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1924     ok(RPC_S_OK == RpcBindingFree(&IMixedServer_IfHandle), "RpcBindingFree\n");
1925   }
1926   else if (strcmp(test, "tcp_secure") == 0)
1927   {
1928     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, iptcp, address, port, NULL, &binding), "RpcStringBindingCompose\n");
1929     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle), "RpcBindingFromStringBinding\n");
1930 
1931     set_auth_info(IMixedServer_IfHandle);
1932     authinfo_test(RPC_PROTSEQ_TCP, 1);
1933     test_is_server_listening(IMixedServer_IfHandle, RPC_S_ACCESS_DENIED);
1934 
1935     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1936     ok(RPC_S_OK == RpcBindingFree(&IMixedServer_IfHandle), "RpcBindingFree\n");
1937   }
1938   else if (strcmp(test, "ncalrpc_basic") == 0)
1939   {
1940     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding), "RpcStringBindingCompose\n");
1941     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle), "RpcBindingFromStringBinding\n");
1942 
1943     run_tests(); /* can cause RPC_X_BAD_STUB_DATA exception */
1944     authinfo_test(RPC_PROTSEQ_LRPC, 0);
1945     test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK);
1946 
1947     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1948     ok(RPC_S_OK == RpcBindingFree(&IMixedServer_IfHandle), "RpcBindingFree\n");
1949   }
1950   else if (strcmp(test, "ncalrpc_autolisten") == 0)
1951   {
1952     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding), "RpcStringBindingCompose\n");
1953     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle), "RpcBindingFromStringBinding\n");
1954 
1955     run_tests();
1956     authinfo_test(RPC_PROTSEQ_LRPC, 0);
1957 todo_wine
1958     test_is_server_listening(IMixedServer_IfHandle, RPC_S_NOT_LISTENING);
1959 
1960     stop_autolisten();
1961     ok(int_return() == INT_CODE, "RPC int_return\n");
1962 
1963     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1964     ok(RPC_S_OK == RpcBindingFree(&IMixedServer_IfHandle), "RpcBindingFree\n");
1965   }
1966   else if (strcmp(test, "ncalrpc_secure") == 0)
1967   {
1968     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding), "RpcStringBindingCompose\n");
1969     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle), "RpcBindingFromStringBinding\n");
1970 
1971     set_auth_info(IMixedServer_IfHandle);
1972     authinfo_test(RPC_PROTSEQ_LRPC, 1);
1973     test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK);
1974 
1975     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1976     ok(RPC_S_OK == RpcBindingFree(&IMixedServer_IfHandle), "RpcBindingFree\n");
1977   }
1978   else if (strcmp(test, "np_basic") == 0)
1979   {
1980     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding), "RpcStringBindingCompose\n");
1981     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle), "RpcBindingFromStringBinding\n");
1982 
1983     test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK);
1984     run_tests();
1985     authinfo_test(RPC_PROTSEQ_NMP, 0);
1986     test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK);
1987     stop();
1988     test_is_server_listening(IMixedServer_IfHandle, RPC_S_NOT_LISTENING);
1989 
1990     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
1991     ok(RPC_S_OK == RpcBindingFree(&IMixedServer_IfHandle), "RpcBindingFree\n");
1992   }
1993   else if (strcmp(test, "np_basic_interp") == 0)
1994   {
1995     set_interp_interface();
1996 
1997     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding), "RpcStringBindingCompose\n");
1998     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IInterpServer_IfHandle), "RpcBindingFromStringBinding\n");
1999 
2000     test_is_server_listening(IInterpServer_IfHandle, RPC_S_OK);
2001     run_tests();
2002     authinfo_test(RPC_PROTSEQ_NMP, 0);
2003     test_is_server_listening(IInterpServer_IfHandle, RPC_S_OK);
2004 
2005     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
2006     ok(RPC_S_OK == RpcBindingFree(&IInterpServer_IfHandle), "RpcBindingFree\n");
2007   }
2008 }
2009 
2010 static void
server(void)2011 server(void)
2012 {
2013   static unsigned char iptcp[] = "ncacn_ip_tcp";
2014   static unsigned char port[] = PORT;
2015   static unsigned char np[] = "ncacn_np";
2016   static unsigned char pipe[] = PIPE;
2017   static unsigned char ncalrpc[] = "ncalrpc";
2018   static unsigned char guid[] = "00000000-4114-0704-2301-000000000000";
2019   RPC_STATUS status, iptcp_status, np_status, ncalrpc_status;
2020   DWORD ret;
2021 
2022   /* needed for tests involving interface pointers */
2023   CoInitializeEx(NULL, COINIT_MULTITHREADED);
2024 
2025   iptcp_status = RpcServerUseProtseqEpA(iptcp, 20, port, NULL);
2026   ok(iptcp_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_ip_tcp) failed with status %d\n", iptcp_status);
2027 
2028   ncalrpc_status = RpcServerUseProtseqEpA(ncalrpc, 0, guid, NULL);
2029   ok(ncalrpc_status == RPC_S_OK, "RpcServerUseProtseqEp(ncalrpc) failed with status %d\n", ncalrpc_status);
2030 
2031   np_status = RpcServerUseProtseqEpA(np, 0, pipe, NULL);
2032   if (np_status == RPC_S_PROTSEQ_NOT_SUPPORTED)
2033     skip("Protocol sequence ncacn_np is not supported\n");
2034   else
2035     ok(np_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", np_status);
2036 
2037   if (pRpcServerRegisterIfEx)
2038   {
2039     trace("Using RpcServerRegisterIfEx\n");
2040     status = pRpcServerRegisterIfEx(s_IMixedServer_v0_0_s_ifspec, NULL, NULL,
2041                                     RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH,
2042                                     RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL);
2043     ok(status == RPC_S_OK, "RpcServerRegisterIfEx failed with status %d\n", status);
2044     status = pRpcServerRegisterIfEx(s_IInterpServer_v0_0_s_ifspec, NULL, NULL,
2045                                     RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH,
2046                                     RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL);
2047     ok(status == RPC_S_OK, "RpcServerRegisterIfEx failed with status %d\n", status);
2048   }
2049   else
2050   {
2051     status = RpcServerRegisterIf(s_IMixedServer_v0_0_s_ifspec, NULL, NULL);
2052     ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status);
2053     status = RpcServerRegisterIf(s_IInterpServer_v0_0_s_ifspec, NULL, NULL);
2054     ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status);
2055   }
2056   test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
2057   status = RpcServerListen(1, 20, TRUE);
2058   ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
2059   test_is_server_listening(NULL, RPC_S_OK);
2060   stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
2061   ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError());
2062 
2063   if (iptcp_status == RPC_S_OK)
2064     run_client("tcp_basic");
2065   else
2066     skip("tcp tests skipped due to earlier failure\n");
2067 
2068   if (ncalrpc_status == RPC_S_OK)
2069   {
2070     run_client("ncalrpc_basic");
2071 
2072     /* we don't need to register RPC_C_AUTHN_WINNT for ncalrpc */
2073     run_client("ncalrpc_secure");
2074   }
2075   else
2076     skip("lrpc tests skipped due to earlier failure\n");
2077 
2078   if (np_status == RPC_S_OK)
2079   {
2080     run_client("np_basic_interp");
2081     run_client("np_basic");
2082   }
2083   else
2084   {
2085     skip("np_basic tests skipped due to earlier failure\n");
2086     /* np client is what signals stop_event, so bail out if we didn't run do it */
2087     return;
2088   }
2089 
2090   ret = WaitForSingleObject(stop_event, 1000);
2091   ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
2092 
2093   /* if the stop event didn't fire then RpcMgmtWaitServerListen will wait
2094    * forever, so don't bother calling it in this case */
2095   if (ret == WAIT_OBJECT_0)
2096   {
2097     status = RpcMgmtWaitServerListen();
2098     ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status);
2099   }
2100 
2101   CloseHandle(stop_event);
2102   stop_event = NULL;
2103 
2104   if (pRpcServerRegisterIfEx)
2105   {
2106     status = pRpcServerRegisterIfEx(s_IMixedServer_v0_0_s_ifspec, NULL, NULL,
2107         RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH | RPC_IF_AUTOLISTEN,
2108         RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL);
2109     ok(status == RPC_S_OK, "RpcServerRegisterIf() failed: %u\n", status);
2110 
2111     run_client("ncalrpc_autolisten");
2112 
2113     status = RpcServerUnregisterIf(s_IMixedServer_v0_0_s_ifspec, NULL, TRUE);
2114     ok(status == RPC_S_OK, "RpcServerUnregisterIf() failed: %u\n", status);
2115   }
2116 
2117   CoUninitialize();
2118 }
2119 
listen_test_client_thread(void * binding)2120 static DWORD WINAPI listen_test_client_thread(void *binding)
2121 {
2122     RPC_STATUS status;
2123 
2124     status = RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle);
2125     ok(status == RPC_S_OK, "RpcBindingFromStringBinding\n");
2126 
2127     test_is_server_listening(IMixedServer_IfHandle, RPC_S_OK);
2128     stop();
2129     trace("stopped\n");
2130 
2131     status = RpcBindingFree(&IMixedServer_IfHandle);
2132     ok(status == RPC_S_OK, "RpcBindingFree\n");
2133     return 0;
2134 }
2135 
wait_listen_proc(void * arg)2136 static DWORD WINAPI wait_listen_proc(void *arg)
2137 {
2138     RPC_STATUS status;
2139 
2140     trace("waiting\n");
2141     status = RpcMgmtWaitServerListen();
2142     ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status);
2143     trace("done\n");
2144 
2145     return 0;
2146 }
2147 
test_stop_wait_for_call(unsigned char * binding)2148 static void test_stop_wait_for_call(unsigned char *binding)
2149 {
2150     HANDLE client_thread, wait_listen_thread;
2151     RPC_STATUS status;
2152     DWORD ret;
2153 
2154     status = RpcServerListen(1, 20, TRUE);
2155     ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
2156     test_is_server_listening(NULL, RPC_S_OK);
2157 
2158     stop_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL);
2159     ok(stop_wait_event != NULL, "CreateEvent failed with error %d\n", GetLastError());
2160     stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
2161     ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError());
2162 
2163     wait_listen_thread = CreateThread(NULL, 0, wait_listen_proc, 0, 0, NULL);
2164     ok(wait_listen_thread != NULL, "CreateThread failed\n");
2165 
2166     client_thread = CreateThread(NULL, 0, listen_test_client_thread, binding, 0, NULL);
2167     ok(client_thread != NULL, "CreateThread failed\n");
2168     CloseHandle(client_thread);
2169 
2170     ret = WaitForSingleObject(stop_event, 10000);
2171     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
2172 
2173     status = RpcMgmtStopServerListening(NULL);
2174     ok(status == RPC_S_OK, "RpcMgmtStopServerListening\n");
2175     test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
2176 
2177     ret = WaitForSingleObject(wait_listen_thread, 500);
2178     ok(WAIT_TIMEOUT == ret, "WaitForSingleObject\n");
2179 
2180     SetEvent(stop_wait_event);
2181 
2182     ret = WaitForSingleObject(wait_listen_thread, 10000);
2183     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject returned %u\n", ret);
2184 
2185     CloseHandle(wait_listen_thread);
2186 
2187     CloseHandle(stop_wait_event);
2188     stop_wait_event = NULL;
2189     CloseHandle(stop_event);
2190     stop_event = NULL;
2191 }
2192 
test_server_listening(void)2193 static void test_server_listening(void)
2194 {
2195     static unsigned char np[] = "ncacn_np";
2196     static unsigned char address_np[] = "\\\\.";
2197     static unsigned char pipe[] = PIPE "listen_test";
2198     static unsigned char ncalrpc[] = "ncalrpc";
2199     static unsigned char guid[] = "00000000-4114-0704-2302-000000000000";
2200     unsigned char *binding;
2201     RPC_STATUS status;
2202 
2203     status = RpcServerUseProtseqEpA(np, 0, pipe, NULL);
2204     ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", status);
2205 
2206     status = RpcServerRegisterIf(s_IMixedServer_v0_0_s_ifspec, NULL, NULL);
2207     ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status);
2208 
2209     test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
2210     status = RpcServerListen(1, 20, TRUE);
2211     ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
2212     test_is_server_listening(NULL, RPC_S_OK);
2213 
2214     status = RpcServerListen(1, 20, TRUE);
2215     ok(status == RPC_S_ALREADY_LISTENING, "RpcServerListen failed with status %d\n", status);
2216 
2217     status = RpcMgmtStopServerListening(NULL);
2218     ok(status == RPC_S_OK, "RpcMgmtStopServerListening\n");
2219     test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
2220 
2221     status = RpcMgmtWaitServerListen();
2222     ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status);
2223 
2224     status = RpcMgmtWaitServerListen();
2225     ok(status == RPC_S_NOT_LISTENING, "RpcMgmtWaitServerListening failed with status %d\n", status);
2226 
2227     /* test that server stop waits for a call in progress */
2228     status = RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding);
2229     ok(status == RPC_S_OK, "RpcStringBindingCompose\n");
2230 
2231     test_stop_wait_for_call(binding);
2232 
2233     status = RpcStringFreeA(&binding);
2234     ok(status == RPC_S_OK, "RpcStringFree\n");
2235 
2236     /* repeat the test using ncalrpc */
2237     status = RpcServerUseProtseqEpA(ncalrpc, 0, guid, NULL);
2238     ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncalrpc) failed with status %d\n", status);
2239 
2240     status = RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding);
2241     ok(status == RPC_S_OK, "RpcStringBindingCompose\n");
2242 
2243     test_stop_wait_for_call(binding);
2244 
2245     status = RpcStringFreeA(&binding);
2246     ok(status == RPC_S_OK, "RpcStringFree\n");
2247 }
2248 
create_server_process(void)2249 static HANDLE create_server_process(void)
2250 {
2251     SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE };
2252     HANDLE ready_event;
2253     char cmdline[MAX_PATH];
2254     PROCESS_INFORMATION info;
2255     STARTUPINFOA startup;
2256     DWORD ret;
2257 
2258     memset(&startup, 0, sizeof startup);
2259     startup.cb = sizeof startup;
2260 
2261     ready_event = CreateEventW(&sec_attr, TRUE, FALSE, NULL);
2262     ok(ready_event != NULL, "CreateEvent failed: %u\n", GetLastError());
2263 
2264 #ifdef __REACTOS__
2265     sprintf(cmdline, "%s server run %Ix", progname, (UINT_PTR)ready_event);
2266 #else
2267     sprintf(cmdline, "%s server run %lx", progname, (UINT_PTR)ready_event);
2268 #endif
2269     trace("running server process...\n");
2270     ok(CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
2271     ret = WaitForSingleObject(ready_event, 10000);
2272     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
2273 
2274     ok(CloseHandle(info.hThread), "CloseHandle\n");
2275     ok(CloseHandle(ready_event), "CloseHandle\n");
2276     return info.hProcess;
2277 }
2278 
run_server(HANDLE ready_event)2279 static void run_server(HANDLE ready_event)
2280 {
2281     static unsigned char np[] = "ncacn_np";
2282     static unsigned char pipe[] = PIPE "term_test";
2283     RPC_STATUS status;
2284     BOOL ret;
2285 
2286     status = RpcServerUseProtseqEpA(np, 0, pipe, NULL);
2287     ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", status);
2288 
2289     status = RpcServerRegisterIf(s_IMixedServer_v0_0_s_ifspec, NULL, NULL);
2290     ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status);
2291 
2292     test_is_server_listening(NULL, RPC_S_NOT_LISTENING);
2293     status = RpcServerListen(1, 20, TRUE);
2294     ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
2295 
2296     stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
2297     ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError());
2298 
2299     ret = SetEvent(ready_event);
2300     ok(ret, "SetEvent failed: %u\n", GetLastError());
2301 
2302     ret = WaitForSingleObject(stop_event, 1000);
2303     ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
2304 
2305     status = RpcMgmtWaitServerListen();
2306     ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status);
2307 
2308     CloseHandle(stop_event);
2309     stop_event = NULL;
2310 }
2311 
basic_tests_thread(void * arg)2312 static DWORD WINAPI basic_tests_thread(void *arg)
2313 {
2314     basic_tests();
2315     return 0;
2316 }
2317 
test_reconnect(void)2318 static void test_reconnect(void)
2319 {
2320     static unsigned char np[] = "ncacn_np";
2321     static unsigned char address_np[] = "\\\\.";
2322     static unsigned char pipe[] = PIPE "term_test";
2323     unsigned char *binding;
2324     HANDLE threads[32];
2325     HANDLE server_process;
2326     unsigned i;
2327     DWORD ret;
2328 
2329     server_process = create_server_process();
2330 
2331     ok(RPC_S_OK == RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding), "RpcStringBindingCompose\n");
2332     ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle), "RpcBindingFromStringBinding\n");
2333 
2334     for (i = 0; i < ARRAY_SIZE(threads); i++)
2335     {
2336         threads[i] = CreateThread(NULL, 0, basic_tests_thread, 0, 0, NULL);
2337         ok(threads[i] != NULL, "CreateThread failed: %u\n", GetLastError());
2338     }
2339 
2340     for (i = 0; i < ARRAY_SIZE(threads); i++)
2341     {
2342         ret = WaitForSingleObject(threads[i], 10000);
2343         ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n");
2344         CloseHandle(threads[i]);
2345     }
2346 
2347     stop();
2348 
2349     winetest_wait_child_process(server_process);
2350     ok(CloseHandle(server_process), "CloseHandle\n");
2351 
2352     /* create new server, rpcrt4 will connect to it once sending to existing connection fails
2353      * that current connection is broken. */
2354     server_process = create_server_process();
2355     basic_tests();
2356     stop();
2357 
2358     winetest_wait_child_process(server_process);
2359     ok(CloseHandle(server_process), "CloseHandle\n");
2360 
2361     ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n");
2362     ok(RPC_S_OK == RpcBindingFree(&IMixedServer_IfHandle), "RpcBindingFree\n");
2363 }
2364 
is_process_elevated(void)2365 static BOOL is_process_elevated(void)
2366 {
2367     HANDLE token;
2368     if (OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token ))
2369     {
2370         TOKEN_ELEVATION_TYPE type;
2371         DWORD size;
2372         BOOL ret;
2373 
2374         ret = GetTokenInformation( token, TokenElevationType, &type, sizeof(type), &size );
2375         CloseHandle( token );
2376         return (ret && type == TokenElevationTypeFull);
2377     }
2378     return FALSE;
2379 }
2380 
is_firewall_enabled(void)2381 static BOOL is_firewall_enabled(void)
2382 {
2383     HRESULT hr, init;
2384     INetFwMgr *mgr = NULL;
2385     INetFwPolicy *policy = NULL;
2386     INetFwProfile *profile = NULL;
2387     VARIANT_BOOL enabled = VARIANT_FALSE;
2388 
2389     init = CoInitializeEx( 0, COINIT_APARTMENTTHREADED );
2390 
2391     hr = CoCreateInstance( &CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr,
2392                            (void **)&mgr );
2393     ok( hr == S_OK, "got %08x\n", hr );
2394     if (hr != S_OK) goto done;
2395 
2396     hr = INetFwMgr_get_LocalPolicy( mgr, &policy );
2397     ok( hr == S_OK, "got %08x\n", hr );
2398     if (hr != S_OK) goto done;
2399 
2400     hr = INetFwPolicy_get_CurrentProfile( policy, &profile );
2401     if (hr != S_OK) goto done;
2402 
2403     hr = INetFwProfile_get_FirewallEnabled( profile, &enabled );
2404     ok( hr == S_OK, "got %08x\n", hr );
2405 
2406 done:
2407     if (policy) INetFwPolicy_Release( policy );
2408     if (profile) INetFwProfile_Release( profile );
2409     if (mgr) INetFwMgr_Release( mgr );
2410     if (SUCCEEDED( init )) CoUninitialize();
2411     return (enabled == VARIANT_TRUE);
2412 }
2413 
2414 enum firewall_op
2415 {
2416     APP_ADD,
2417     APP_REMOVE
2418 };
2419 
set_firewall(enum firewall_op op)2420 static HRESULT set_firewall( enum firewall_op op )
2421 {
2422     static const WCHAR testW[] = {'r','p','c','r','t','4','_','t','e','s','t',0};
2423     HRESULT hr, init;
2424     INetFwMgr *mgr = NULL;
2425     INetFwPolicy *policy = NULL;
2426     INetFwProfile *profile = NULL;
2427     INetFwAuthorizedApplication *app = NULL;
2428     INetFwAuthorizedApplications *apps = NULL;
2429     BSTR name, image = SysAllocStringLen( NULL, MAX_PATH );
2430 
2431     if (!GetModuleFileNameW( NULL, image, MAX_PATH ))
2432     {
2433         SysFreeString( image );
2434         return E_FAIL;
2435     }
2436     init = CoInitializeEx( 0, COINIT_APARTMENTTHREADED );
2437 
2438     hr = CoCreateInstance( &CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr,
2439                            (void **)&mgr );
2440     ok( hr == S_OK, "got %08x\n", hr );
2441     if (hr != S_OK) goto done;
2442 
2443     hr = INetFwMgr_get_LocalPolicy( mgr, &policy );
2444     ok( hr == S_OK, "got %08x\n", hr );
2445     if (hr != S_OK) goto done;
2446 
2447     hr = INetFwPolicy_get_CurrentProfile( policy, &profile );
2448     if (hr != S_OK) goto done;
2449 
2450     hr = INetFwProfile_get_AuthorizedApplications( profile, &apps );
2451     ok( hr == S_OK, "got %08x\n", hr );
2452     if (hr != S_OK) goto done;
2453 
2454     hr = CoCreateInstance( &CLSID_NetFwAuthorizedApplication, NULL, CLSCTX_INPROC_SERVER,
2455                            &IID_INetFwAuthorizedApplication, (void **)&app );
2456     ok( hr == S_OK, "got %08x\n", hr );
2457     if (hr != S_OK) goto done;
2458 
2459     hr = INetFwAuthorizedApplication_put_ProcessImageFileName( app, image );
2460     if (hr != S_OK) goto done;
2461 
2462     name = SysAllocString( testW );
2463     hr = INetFwAuthorizedApplication_put_Name( app, name );
2464     SysFreeString( name );
2465     ok( hr == S_OK, "got %08x\n", hr );
2466     if (hr != S_OK) goto done;
2467 
2468     if (op == APP_ADD)
2469         hr = INetFwAuthorizedApplications_Add( apps, app );
2470     else if (op == APP_REMOVE)
2471         hr = INetFwAuthorizedApplications_Remove( apps, image );
2472     else
2473         hr = E_INVALIDARG;
2474 
2475 done:
2476     if (app) INetFwAuthorizedApplication_Release( app );
2477     if (apps) INetFwAuthorizedApplications_Release( apps );
2478     if (policy) INetFwPolicy_Release( policy );
2479     if (profile) INetFwProfile_Release( profile );
2480     if (mgr) INetFwMgr_Release( mgr );
2481     if (SUCCEEDED( init )) CoUninitialize();
2482     SysFreeString( image );
2483     return hr;
2484 }
2485 
START_TEST(server)2486 START_TEST(server)
2487 {
2488   ULONG size = 0;
2489   int argc;
2490   char **argv;
2491   BOOL firewall_enabled = is_firewall_enabled(), firewall_disabled = FALSE;
2492 
2493   InitFunctionPointers();
2494   set_mixed_interface();
2495 
2496   ok(!GetUserNameExA(NameSamCompatible, NULL, &size), "GetUserNameExA\n");
2497   domain_and_user = HeapAlloc(GetProcessHeap(), 0, size);
2498   ok(GetUserNameExA(NameSamCompatible, domain_and_user, &size), "GetUserNameExA\n");
2499 
2500   argc = winetest_get_mainargs(&argv);
2501   progname = argv[0];
2502 
2503   if (argc == 3)
2504   {
2505     RpcTryExcept
2506     {
2507       client(argv[2]);
2508     }
2509     RpcExcept(TRUE)
2510     {
2511       trace("Exception %d\n", RpcExceptionCode());
2512     }
2513     RpcEndExcept
2514   }
2515   else if (argc == 4)
2516   {
2517     if (!strcmp(argv[3], "listen"))
2518     {
2519       test_server_listening();
2520     }
2521     else if(!strcmp(argv[2], "run"))
2522     {
2523       UINT_PTR event;
2524 #ifdef __REACTOS__
2525       sscanf(argv[3], "%Ix", &event);
2526 #else
2527       sscanf(argv[3], "%lx", &event);
2528 #endif
2529       run_server((HANDLE)event);
2530     }
2531   }
2532   else
2533   {
2534     if (firewall_enabled)
2535     {
2536       if (is_process_elevated())
2537       {
2538         HRESULT hr = set_firewall(APP_ADD);
2539         if (hr == S_OK)
2540         {
2541           firewall_enabled = FALSE;
2542           firewall_disabled = TRUE;
2543         }
2544         else
2545         {
2546           skip("can't authorize app in firewall %08x\n", hr);
2547         }
2548       }
2549       else
2550       {
2551           trace("no privileges, skipping tests to avoid firewall dialog\n");
2552       }
2553     }
2554 
2555     if (!firewall_enabled) server();
2556 
2557     /* Those tests cause occasional crashes on winxp and win2k3 */
2558     if (GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "RpcExceptionFilter"))
2559         test_reconnect();
2560     else
2561         win_skip("Skipping reconnect tests on too old Windows version\n");
2562 
2563     run_client("test listen");
2564     if (firewall_disabled) set_firewall(APP_REMOVE);
2565   }
2566 
2567   HeapFree(GetProcessHeap(), 0, domain_and_user);
2568 }
2569