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