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 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 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 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 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 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 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 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 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) 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) 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 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 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 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 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 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 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 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 sprintf(cmdline, "%s server run %lx", progname, (UINT_PTR)ready_event); 2265 trace("running server process...\n"); 2266 ok(CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); 2267 ret = WaitForSingleObject(ready_event, 10000); 2268 ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); 2269 2270 ok(CloseHandle(info.hThread), "CloseHandle\n"); 2271 ok(CloseHandle(ready_event), "CloseHandle\n"); 2272 return info.hProcess; 2273 } 2274 2275 static void run_server(HANDLE ready_event) 2276 { 2277 static unsigned char np[] = "ncacn_np"; 2278 static unsigned char pipe[] = PIPE "term_test"; 2279 RPC_STATUS status; 2280 BOOL ret; 2281 2282 status = RpcServerUseProtseqEpA(np, 0, pipe, NULL); 2283 ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", status); 2284 2285 status = RpcServerRegisterIf(s_IMixedServer_v0_0_s_ifspec, NULL, NULL); 2286 ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status); 2287 2288 test_is_server_listening(NULL, RPC_S_NOT_LISTENING); 2289 status = RpcServerListen(1, 20, TRUE); 2290 ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status); 2291 2292 stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); 2293 ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError()); 2294 2295 ret = SetEvent(ready_event); 2296 ok(ret, "SetEvent failed: %u\n", GetLastError()); 2297 2298 ret = WaitForSingleObject(stop_event, 1000); 2299 ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); 2300 2301 status = RpcMgmtWaitServerListen(); 2302 ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status); 2303 2304 CloseHandle(stop_event); 2305 stop_event = NULL; 2306 } 2307 2308 static DWORD WINAPI basic_tests_thread(void *arg) 2309 { 2310 basic_tests(); 2311 return 0; 2312 } 2313 2314 static void test_reconnect(void) 2315 { 2316 static unsigned char np[] = "ncacn_np"; 2317 static unsigned char address_np[] = "\\\\."; 2318 static unsigned char pipe[] = PIPE "term_test"; 2319 unsigned char *binding; 2320 HANDLE threads[32]; 2321 HANDLE server_process; 2322 unsigned i; 2323 DWORD ret; 2324 2325 server_process = create_server_process(); 2326 2327 ok(RPC_S_OK == RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding), "RpcStringBindingCompose\n"); 2328 ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IMixedServer_IfHandle), "RpcBindingFromStringBinding\n"); 2329 2330 for (i = 0; i < ARRAY_SIZE(threads); i++) 2331 { 2332 threads[i] = CreateThread(NULL, 0, basic_tests_thread, 0, 0, NULL); 2333 ok(threads[i] != NULL, "CreateThread failed: %u\n", GetLastError()); 2334 } 2335 2336 for (i = 0; i < ARRAY_SIZE(threads); i++) 2337 { 2338 ret = WaitForSingleObject(threads[i], 10000); 2339 ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); 2340 CloseHandle(threads[i]); 2341 } 2342 2343 stop(); 2344 2345 winetest_wait_child_process(server_process); 2346 ok(CloseHandle(server_process), "CloseHandle\n"); 2347 2348 /* create new server, rpcrt4 will connect to it once sending to existing connection fails 2349 * that current connection is broken. */ 2350 server_process = create_server_process(); 2351 basic_tests(); 2352 stop(); 2353 2354 winetest_wait_child_process(server_process); 2355 ok(CloseHandle(server_process), "CloseHandle\n"); 2356 2357 ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); 2358 ok(RPC_S_OK == RpcBindingFree(&IMixedServer_IfHandle), "RpcBindingFree\n"); 2359 } 2360 2361 static BOOL is_process_elevated(void) 2362 { 2363 HANDLE token; 2364 if (OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token )) 2365 { 2366 TOKEN_ELEVATION_TYPE type; 2367 DWORD size; 2368 BOOL ret; 2369 2370 ret = GetTokenInformation( token, TokenElevationType, &type, sizeof(type), &size ); 2371 CloseHandle( token ); 2372 return (ret && type == TokenElevationTypeFull); 2373 } 2374 return FALSE; 2375 } 2376 2377 static BOOL is_firewall_enabled(void) 2378 { 2379 HRESULT hr, init; 2380 INetFwMgr *mgr = NULL; 2381 INetFwPolicy *policy = NULL; 2382 INetFwProfile *profile = NULL; 2383 VARIANT_BOOL enabled = VARIANT_FALSE; 2384 2385 init = CoInitializeEx( 0, COINIT_APARTMENTTHREADED ); 2386 2387 hr = CoCreateInstance( &CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr, 2388 (void **)&mgr ); 2389 ok( hr == S_OK, "got %08x\n", hr ); 2390 if (hr != S_OK) goto done; 2391 2392 hr = INetFwMgr_get_LocalPolicy( mgr, &policy ); 2393 ok( hr == S_OK, "got %08x\n", hr ); 2394 if (hr != S_OK) goto done; 2395 2396 hr = INetFwPolicy_get_CurrentProfile( policy, &profile ); 2397 if (hr != S_OK) goto done; 2398 2399 hr = INetFwProfile_get_FirewallEnabled( profile, &enabled ); 2400 ok( hr == S_OK, "got %08x\n", hr ); 2401 2402 done: 2403 if (policy) INetFwPolicy_Release( policy ); 2404 if (profile) INetFwProfile_Release( profile ); 2405 if (mgr) INetFwMgr_Release( mgr ); 2406 if (SUCCEEDED( init )) CoUninitialize(); 2407 return (enabled == VARIANT_TRUE); 2408 } 2409 2410 enum firewall_op 2411 { 2412 APP_ADD, 2413 APP_REMOVE 2414 }; 2415 2416 static HRESULT set_firewall( enum firewall_op op ) 2417 { 2418 static const WCHAR testW[] = {'r','p','c','r','t','4','_','t','e','s','t',0}; 2419 HRESULT hr, init; 2420 INetFwMgr *mgr = NULL; 2421 INetFwPolicy *policy = NULL; 2422 INetFwProfile *profile = NULL; 2423 INetFwAuthorizedApplication *app = NULL; 2424 INetFwAuthorizedApplications *apps = NULL; 2425 BSTR name, image = SysAllocStringLen( NULL, MAX_PATH ); 2426 2427 if (!GetModuleFileNameW( NULL, image, MAX_PATH )) 2428 { 2429 SysFreeString( image ); 2430 return E_FAIL; 2431 } 2432 init = CoInitializeEx( 0, COINIT_APARTMENTTHREADED ); 2433 2434 hr = CoCreateInstance( &CLSID_NetFwMgr, NULL, CLSCTX_INPROC_SERVER, &IID_INetFwMgr, 2435 (void **)&mgr ); 2436 ok( hr == S_OK, "got %08x\n", hr ); 2437 if (hr != S_OK) goto done; 2438 2439 hr = INetFwMgr_get_LocalPolicy( mgr, &policy ); 2440 ok( hr == S_OK, "got %08x\n", hr ); 2441 if (hr != S_OK) goto done; 2442 2443 hr = INetFwPolicy_get_CurrentProfile( policy, &profile ); 2444 if (hr != S_OK) goto done; 2445 2446 hr = INetFwProfile_get_AuthorizedApplications( profile, &apps ); 2447 ok( hr == S_OK, "got %08x\n", hr ); 2448 if (hr != S_OK) goto done; 2449 2450 hr = CoCreateInstance( &CLSID_NetFwAuthorizedApplication, NULL, CLSCTX_INPROC_SERVER, 2451 &IID_INetFwAuthorizedApplication, (void **)&app ); 2452 ok( hr == S_OK, "got %08x\n", hr ); 2453 if (hr != S_OK) goto done; 2454 2455 hr = INetFwAuthorizedApplication_put_ProcessImageFileName( app, image ); 2456 if (hr != S_OK) goto done; 2457 2458 name = SysAllocString( testW ); 2459 hr = INetFwAuthorizedApplication_put_Name( app, name ); 2460 SysFreeString( name ); 2461 ok( hr == S_OK, "got %08x\n", hr ); 2462 if (hr != S_OK) goto done; 2463 2464 if (op == APP_ADD) 2465 hr = INetFwAuthorizedApplications_Add( apps, app ); 2466 else if (op == APP_REMOVE) 2467 hr = INetFwAuthorizedApplications_Remove( apps, image ); 2468 else 2469 hr = E_INVALIDARG; 2470 2471 done: 2472 if (app) INetFwAuthorizedApplication_Release( app ); 2473 if (apps) INetFwAuthorizedApplications_Release( apps ); 2474 if (policy) INetFwPolicy_Release( policy ); 2475 if (profile) INetFwProfile_Release( profile ); 2476 if (mgr) INetFwMgr_Release( mgr ); 2477 if (SUCCEEDED( init )) CoUninitialize(); 2478 SysFreeString( image ); 2479 return hr; 2480 } 2481 2482 START_TEST(server) 2483 { 2484 ULONG size = 0; 2485 int argc; 2486 char **argv; 2487 BOOL firewall_enabled = is_firewall_enabled(), firewall_disabled = FALSE; 2488 2489 InitFunctionPointers(); 2490 set_mixed_interface(); 2491 2492 ok(!GetUserNameExA(NameSamCompatible, NULL, &size), "GetUserNameExA\n"); 2493 domain_and_user = HeapAlloc(GetProcessHeap(), 0, size); 2494 ok(GetUserNameExA(NameSamCompatible, domain_and_user, &size), "GetUserNameExA\n"); 2495 2496 argc = winetest_get_mainargs(&argv); 2497 progname = argv[0]; 2498 2499 if (argc == 3) 2500 { 2501 RpcTryExcept 2502 { 2503 client(argv[2]); 2504 } 2505 RpcExcept(TRUE) 2506 { 2507 trace("Exception %d\n", RpcExceptionCode()); 2508 } 2509 RpcEndExcept 2510 } 2511 else if (argc == 4) 2512 { 2513 if (!strcmp(argv[3], "listen")) 2514 { 2515 test_server_listening(); 2516 } 2517 else if(!strcmp(argv[2], "run")) 2518 { 2519 UINT_PTR event; 2520 sscanf(argv[3], "%lx", &event); 2521 run_server((HANDLE)event); 2522 } 2523 } 2524 else 2525 { 2526 if (firewall_enabled) 2527 { 2528 if (is_process_elevated()) 2529 { 2530 HRESULT hr = set_firewall(APP_ADD); 2531 if (hr == S_OK) 2532 { 2533 firewall_enabled = FALSE; 2534 firewall_disabled = TRUE; 2535 } 2536 else 2537 { 2538 skip("can't authorize app in firewall %08x\n", hr); 2539 } 2540 } 2541 else 2542 { 2543 trace("no privileges, skipping tests to avoid firewall dialog\n"); 2544 } 2545 } 2546 2547 if (!firewall_enabled) server(); 2548 2549 /* Those tests cause occasional crashes on winxp and win2k3 */ 2550 if (GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "RpcExceptionFilter")) 2551 test_reconnect(); 2552 else 2553 win_skip("Skipping reconnect tests on too old Windows version\n"); 2554 2555 run_client("test listen"); 2556 if (firewall_disabled) set_firewall(APP_REMOVE); 2557 } 2558 2559 HeapFree(GetProcessHeap(), 0, domain_and_user); 2560 } 2561