1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** NAME 79** 80** cs_s_stub.c 81** 82** FACILITY: 83** 84** Remote Procedure Call (RPC) 85** I18N Character Call (RPC) 86** 87** ABSTRACT: 88** 89** 90*/ 91#include <commonp.h> /* include nbase.h lbase.h internally */ 92#include <ns.h> 93#include <com.h> 94#include <nsp.h> 95#include <dce/idlbase.h> /* definitions for idl_cs_* */ 96#include <dce/rpcsts.h> 97#include <codesets.h> /* Data definitions for I18N NSI 98 sub-component */ 99#include <dce/codesets_stub.h> /* Stub support routines */ 100 101#include <stdio.h> /* definition of NULL */ 102#include <stdlib.h> /* definition of MB_CUR_MAX */ 103#include <langinfo.h> /* definition of nl_langinfo routine */ 104 105#include <codesets.h> 106#include <cs_s.h> /* Private defs for code set interoperability */ 107 108 109/* 110**++ 111** ROUTINE NAME: cs_byte_to_netcs 112** 113** SCOPE: PUBLIC - declared in dce/codesets_stub.h 114** 115** DESCRIPTION: 116** 117** Convert an encoding of a local data to network encoding, based on 118** the information from a tag. 119** 120** INPUTS: 121** 122** h Binding handle 123** 124** tag Identifies the code set that will be used on the wire. 125** 126** ldata Address of the local data. 127** 128** l_data_len The number of "byte" data elements to be processed. 129** 130** OUTPUTS: 131** 132** wdata Address to which the converted data is to be written. 133** 134** p_w_data_len NULL if fixed array is being marshalled. 135** The address to which the routine writes the 136** on-the-wire data length. 137** 138** status The status of the operation. 139** Can be one of: 140** rpc_s_ok 141** rpc_ss_incompatible_codesets 142** or a status returned from a called routine. 143** 144** IMPLICIT INPUTS: none 145** 146** IMPLICIT OUTPUTS: none 147** 148** FUNCTION VALUE: void 149** 150** SIDE EFFECTS: none 151** 152**-- 153*/ 154 155PUBLIC void cs_byte_to_netcs 156( 157 rpc_binding_handle_t h, 158 unsigned32 tag, 159 idl_byte *ldata, 160 unsigned32 l_data_len, 161 idl_byte *wdata, 162 unsigned32 *p_w_data_len, 163 error_status_t *status 164) 165{ 166 char *current_codeset; 167 unsigned32 current_rgy_codeset; 168 int i; 169 idl_byte *wdata_temp, *ldata_temp; 170 171 rpc_cs_method_eval_p_t method_p; 172 rpc_cs_tags_eval_p_t tags_p; 173 rpc_binding_rep_p_t bind_p; 174 175 bind_p = (rpc_binding_rep_p_t)h; 176 if (!RPC_BINDING_IS_SERVER (bind_p)) 177 { 178 switch (bind_p->cs_eval.key) 179 { 180 case RPC_CS_EVAL_METHOD: 181 method_p = &bind_p->cs_eval.tagged_union.method_key; 182 183 switch (method_p->method) 184 { 185 case RPC_EVAL_NO_CONVERSION: 186 case RPC_EVAL_RMIR_MODEL: 187 case RPC_EVAL_SMIR_MODEL: 188 wdata_temp = wdata; 189 ldata_temp = ldata; 190 for (i=0; i<= l_data_len; i++) 191 *wdata_temp++ = *ldata_temp++; 192 193 if (p_w_data_len != NULL) 194 { 195 *p_w_data_len = strlen((char *)wdata) + 1; 196 } 197 198 *status = rpc_s_ok; 199 break; 200 201 case RPC_EVAL_CMIR_MODEL: 202 case RPC_EVAL_INTERMEDIATE_MODEL: 203 case RPC_EVAL_UNIVERSAL_MODEL: 204 205 stub_conversion ( 206 h, 207 RPC_BINDING_IS_SERVER (bind_p), 208 method_p->tags.client_tag, 209 tag, 210 ldata, 211 l_data_len, 212 wdata, 213 p_w_data_len, 214 status ); 215 216 if (p_w_data_len != NULL) 217 { 218 *p_w_data_len = strlen((char *)wdata) + 1; 219 } 220 221 break; 222 223 default: 224 *status = rpc_s_ss_incompatible_codesets; 225 break; 226 227 } 228 break; 229 230 case RPC_CS_EVAL_TAGS: 231 232 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 233 234 /* 235 * Determine the conversion type. 236 */ 237 if (tag == tags_p->client_tag) 238 /* No conversion required */ 239 { 240 wdata_temp = wdata; 241 ldata_temp = ldata; 242 for (i=0; i<= l_data_len; i++) 243 *wdata_temp++ = *ldata_temp++; 244 245 if (p_w_data_len != NULL) 246 { 247 *p_w_data_len = strlen((char *)wdata) + 1; 248 } 249 250 *status = rpc_s_ok; 251 } 252 else 253 { 254 stub_conversion ( 255 h, 256 RPC_BINDING_IS_SERVER (bind_p), 257 tags_p->client_tag, 258 tag, 259 ldata, 260 l_data_len, 261 wdata, 262 p_w_data_len, 263 status ); 264 265 if (p_w_data_len != NULL) 266 { 267 *p_w_data_len = strlen((char *)wdata) + 1; 268 } 269 } 270 break; 271 272 default: 273 *status = rpc_s_ss_incompatible_codesets; 274 break; 275 } 276 } 277 else /* server side */ 278 { 279 /* 280 * Get the code set info from the current locale. 281 */ 282 current_codeset = nl_langinfo(CODESET); 283 dce_cs_loc_to_rgy( 284 (unsigned_char_p_t)current_codeset, 285 ¤t_rgy_codeset, 286 NULL, NULL, 287 status); 288 289 if (*status != dce_cs_c_ok) 290 { 291 /* codeset registry error */ 292 *status = rpc_s_ok; 293 return; 294 } 295 /* 296 * Determine the conversion type. 297 */ 298 if (tag == current_rgy_codeset) 299 /* No conversion required */ 300 { 301 wdata_temp = wdata; 302 ldata_temp = ldata; 303 for (i=0; i<= l_data_len; i++) 304 *wdata_temp++ = *ldata_temp++; 305 306 if (p_w_data_len != NULL) 307 { 308 *p_w_data_len = strlen((char *)wdata) + 1; 309 } 310 311 *status = rpc_s_ok; 312 } 313 else 314 { 315 stub_conversion ( 316 h, 317 RPC_BINDING_IS_SERVER (bind_p), 318 current_rgy_codeset, 319 tag, 320 ldata, 321 l_data_len, 322 wdata, 323 p_w_data_len, 324 status ); 325 326 if (p_w_data_len != NULL) 327 { 328 *p_w_data_len = strlen((char *)wdata) + 1; 329 } 330 } 331 } 332 return; 333} 334 335 336/* 337**++ 338** ROUTINE NAME: wchar_t_to_netcs 339** 340** SCOPE: PUBLIC - declared in dce/codesets_stub.h 341** 342** DESCRIPTION: 343** 344** Convert an encoding of a local data to network encoding, based on 345** the information from a tag. 346** 347** INPUTS: 348** 349** h Binding handle 350** 351** tag Identifies the code set that will be used on the wire. 352** 353** ldata Address of the local data. 354** 355** l_data_len The number of "byte" data elements to be processed. 356** 357** OUTPUTS: 358** 359** wdata Address to which the converted data is to be written. 360** 361** p_w_data_len NULL if fixed array is being marshalled. 362** The address to which the routine writes the 363** on-the-wire data length. 364** 365** status The status of the operation. 366** Can be one of: 367** rpc_s_ok 368** rpc_ss_incompatible_codesets 369** or a status returned from a called routine. 370** 371** IMPLICIT INPUTS: none 372** 373** IMPLICIT OUTPUTS: none 374** 375** FUNCTION VALUE: void 376** 377** SIDE EFFECTS: none 378** 379**-- 380*/ 381 382PUBLIC void wchar_t_to_netcs 383( 384 rpc_binding_handle_t h, 385 unsigned32 tag, 386 wchar_t *ldata, 387 unsigned32 l_data_len, 388 idl_byte *wdata, 389 unsigned32 *p_w_data_len, 390 error_status_t *status 391) 392{ 393 char *current_codeset; 394 unsigned32 current_rgy_codeset; 395 idl_byte *byte_ldata; 396 idl_byte *t_byte_ldata; 397 size_t ldata_length; 398 size_t conv_ret; 399 int i; 400 idl_byte *wdata_temp, *ldata_temp; 401 402 rpc_cs_method_eval_p_t method_p; 403 rpc_cs_tags_eval_p_t tags_p; 404 rpc_binding_rep_p_t bind_p; 405 406 /* 407 * Allocate the largest buffer for the conversion. 408 */ 409 ldata_length = l_data_len * MB_CUR_MAX + MB_CUR_MAX; 410 411 RPC_MEM_ALLOC ( 412 byte_ldata, 413 unsigned_char_p_t, 414 ldata_length, 415 RPC_C_MEM_STRING, 416 RPC_C_MEM_WAITOK); 417 418 /* Initialize the buffer */ 419 t_byte_ldata = byte_ldata; 420 i = ldata_length; 421 while (i--) 422 *t_byte_ldata++ = '\0'; 423 424 conv_ret = wcstombs((char *)byte_ldata, ldata, ldata_length); 425 426 if (conv_ret == -1) /* Conversion error took place */ 427 { 428 *status = rpc_s_ss_invalid_char_input; 429 RPC_MEM_FREE(byte_ldata, RPC_C_MEM_STRING); 430 return; 431 } 432 433 bind_p = (rpc_binding_rep_p_t)h; 434 if (!RPC_BINDING_IS_SERVER (bind_p)) 435 { 436 switch (bind_p->cs_eval.key) 437 { 438 case RPC_CS_EVAL_METHOD: 439 method_p = &bind_p->cs_eval.tagged_union.method_key; 440 441 switch (method_p->method) 442 { 443 case RPC_EVAL_NO_CONVERSION: 444 case RPC_EVAL_RMIR_MODEL: 445 case RPC_EVAL_SMIR_MODEL: 446 wdata_temp = wdata; 447 ldata_temp = byte_ldata; 448 for (i=0; i<= conv_ret; i++) 449 *wdata_temp++ = *ldata_temp++; 450 451 if (p_w_data_len != NULL) 452 *p_w_data_len = conv_ret; 453 454 *status = rpc_s_ok; 455 break; 456 457 case RPC_EVAL_CMIR_MODEL: 458 case RPC_EVAL_INTERMEDIATE_MODEL: 459 case RPC_EVAL_UNIVERSAL_MODEL: 460 stub_conversion ( 461 h, 462 RPC_BINDING_IS_SERVER (bind_p), 463 method_p->tags.client_tag, 464 tag, 465 byte_ldata, 466 conv_ret, 467 wdata, 468 p_w_data_len, 469 status ); 470 break; 471 472 default: 473 *status = rpc_s_ss_incompatible_codesets; 474 break; 475 476 } 477 break; 478 479 case RPC_CS_EVAL_TAGS: 480 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 481 482 /* 483 * Determine the conversion type. 484 */ 485 if (tag == tags_p->client_tag) 486 /* No conversion required */ 487 { 488 wdata_temp = wdata; 489 ldata_temp = byte_ldata; 490 for (i=0; i<= conv_ret; i++) 491 *wdata_temp++ = *ldata_temp++; 492 493 if (p_w_data_len != NULL) 494 *p_w_data_len = conv_ret; 495 496 *status = rpc_s_ok; 497 } 498 else 499 { 500 stub_conversion ( 501 h, 502 RPC_BINDING_IS_SERVER (bind_p), 503 tags_p->client_tag, 504 tag, 505 byte_ldata, 506 conv_ret, 507 wdata, 508 p_w_data_len, 509 status ); 510 } 511 break; 512 513 default: 514 *status = rpc_s_ss_incompatible_codesets; 515 break; 516 } 517 } 518 else /* server side */ 519 { 520 /* 521 * Get the code set info from the current locale. 522 */ 523 current_codeset = nl_langinfo(CODESET); 524 dce_cs_loc_to_rgy( 525 (unsigned_char_p_t)current_codeset, 526 ¤t_rgy_codeset, 527 NULL, NULL, 528 status); 529 530 if (*status != dce_cs_c_ok) 531 { 532 /* codeset registry error */ 533 *status = rpc_s_ok; 534 RPC_MEM_FREE(byte_ldata, RPC_C_MEM_STRING); 535 return; 536 } 537 /* 538 * Determine the conversion type. 539 */ 540 if (tag == current_rgy_codeset) 541 /* No conversion required */ 542 { 543 wdata_temp = wdata; 544 ldata_temp = byte_ldata; 545 for (i=0; i<= conv_ret; i++) 546 *wdata_temp++ = *ldata_temp++; 547 548 if (p_w_data_len != NULL) 549 *p_w_data_len = conv_ret; 550 551 *status = rpc_s_ok; 552 } 553 else 554 { 555 stub_conversion ( 556 h, 557 RPC_BINDING_IS_SERVER (bind_p), 558 current_rgy_codeset, 559 tag, 560 byte_ldata, 561 conv_ret, 562 wdata, 563 p_w_data_len, 564 status ); 565 } 566 } 567 RPC_MEM_FREE(byte_ldata, RPC_C_MEM_STRING); 568 return; 569} 570 571 572/* 573**++ 574** ROUTINE NAME: cs_byte_from_netcs 575** 576** SCOPE: PUBLIC - declared in dce/codesets_stub.h 577** 578** DESCRIPTION: 579** 580** Convert an encoding of a network data to local encoding, based on 581** the information from a tag. 582** 583** INPUTS: 584** 585** h Binding handle 586** 587** tag Identifies the code set that will be used on the wire. 588** 589** wdata Address of the network data. 590** 591** w_data_len The number of "byte" data elements to be processed. 592** 593** OUTPUTS: 594** 595** ldata Address to which the converted data is to be written. 596** 597** p_l_data_len NULL if fixed array is being marshalled. 598** The address to which the routine writes the 599** local data length. 600** 601** status The status of the operation. 602** Can be one of: 603** rpc_s_ok 604** rpc_ss_incompatible_codesets 605** or a status returned from a called routine. 606** 607** IMPLICIT INPUTS: none 608** 609** IMPLICIT OUTPUTS: none 610** 611** FUNCTION VALUE: void 612** 613** SIDE EFFECTS: none 614** 615**-- 616*/ 617 618PUBLIC void cs_byte_from_netcs 619( 620 rpc_binding_handle_t h, 621 unsigned32 tag, 622 idl_byte *wdata, 623 unsigned32 w_data_len, 624 unsigned32 l_storage_len, 625 idl_byte *ldata, 626 unsigned32 *p_l_data_len, 627 error_status_t *status 628) 629{ 630 char *current_codeset; 631 unsigned32 current_rgy_codeset; 632 int i; 633 idl_byte *wdata_temp, *ldata_temp; 634 635 rpc_cs_method_eval_p_t method_p; 636 rpc_cs_tags_eval_p_t tags_p; 637 rpc_binding_rep_p_t bind_p; 638 639 bind_p = (rpc_binding_rep_p_t)h; 640 if (!RPC_BINDING_IS_SERVER (bind_p)) 641 { 642 switch (bind_p->cs_eval.key) 643 { 644 case RPC_CS_EVAL_METHOD: 645 method_p = &bind_p->cs_eval.tagged_union.method_key; 646 647 switch (method_p->method) 648 { 649 case RPC_EVAL_NO_CONVERSION: 650 case RPC_EVAL_SMIR_MODEL: 651 wdata_temp = wdata; 652 ldata_temp = ldata; 653 for (i=0; i<= w_data_len; i++) 654 *wdata_temp++ = *ldata_temp++; 655 656 if (p_l_data_len != NULL) 657 { 658 *p_l_data_len = strlen((char *)wdata) + 1; 659 } 660 661 *status = rpc_s_ok; 662 break; 663 664 case RPC_EVAL_CMIR_MODEL: 665 case RPC_EVAL_RMIR_MODEL: 666 case RPC_EVAL_INTERMEDIATE_MODEL: 667 case RPC_EVAL_UNIVERSAL_MODEL: 668 stub_conversion ( 669 h, 670 RPC_BINDING_IS_SERVER (bind_p), 671 tag, 672 method_p->tags.client_tag, 673 wdata, 674 w_data_len, 675 ldata, 676 p_l_data_len, 677 status ); 678 679 if (p_l_data_len != NULL) 680 { 681 *p_l_data_len = strlen((char *)wdata) + 1; 682 } 683 684 break; 685 686 default: 687 *status = rpc_s_ss_incompatible_codesets; 688 break; 689 690 } 691 break; 692 693 case RPC_CS_EVAL_TAGS: 694 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 695 696 /* 697 * Determine the conversion type. 698 */ 699 if (tag == tags_p->client_tag) 700 /* No conversion required */ 701 { 702 wdata_temp = wdata; 703 ldata_temp = ldata; 704 for (i=0; i<= w_data_len; i++) 705 *wdata_temp++ = *ldata_temp++; 706 707 if (p_l_data_len != NULL) 708 { 709 *p_l_data_len = strlen((char *)wdata) + 1; 710 } 711 712 *status = rpc_s_ok; 713 } 714 else 715 { 716 stub_conversion ( 717 h, 718 RPC_BINDING_IS_SERVER (bind_p), 719 tag, 720 tags_p->client_tag, 721 wdata, 722 w_data_len, 723 ldata, 724 p_l_data_len, 725 status ); 726 727 if (p_l_data_len != NULL) 728 { 729 *p_l_data_len = strlen((char *)wdata) + 1; 730 } 731 } 732 break; 733 734 default: 735 *status = rpc_s_ss_incompatible_codesets; 736 break; 737 } 738 } 739 else /* server side */ 740 { 741 /* 742 * Get the code set info from the current locale. 743 */ 744 current_codeset = nl_langinfo(CODESET); 745 dce_cs_loc_to_rgy( 746 (unsigned_char_p_t)current_codeset, 747 ¤t_rgy_codeset, 748 NULL, NULL, 749 status); 750 751 if (*status != dce_cs_c_ok) 752 { 753 /* codeset registry error */ 754 *status = rpc_s_ok; 755 return; 756 } 757 /* 758 * Determine the conversion type. 759 */ 760 if (tag == current_rgy_codeset) 761 /* No conversion required */ 762 { 763 wdata_temp = wdata; 764 ldata_temp = ldata; 765 for (i=0; i<= w_data_len; i++) 766 *wdata_temp++ = *ldata_temp++; 767 768 if (p_l_data_len != NULL) 769 { 770 *p_l_data_len = strlen((char *)wdata) + 1; 771 } 772 773 *status = rpc_s_ok; 774 } 775 else 776 { 777 stub_conversion ( 778 h, 779 RPC_BINDING_IS_SERVER (bind_p), 780 tag, 781 current_rgy_codeset, 782 wdata, 783 w_data_len, 784 ldata, 785 p_l_data_len, 786 status ); 787 788 if (p_l_data_len != NULL) 789 { 790 *p_l_data_len = strlen((char *)wdata) + 1; 791 } 792 } 793 } 794 return; 795} 796 797 798/* 799**++ 800** ROUTINE NAME: wchar_t_from_netcs 801** 802** SCOPE: PUBLIC - declared in dce/codesets_stub.h 803** 804** DESCRIPTION: 805** 806** Convert an encoding of a network data to local encoding, based on 807** the information from a tag. 808** 809** INPUTS: 810** 811** h Binding handle 812** 813** tag Identifies the code set that will be used on the wire. 814** 815** wdata Address of the network data. 816** 817** w_data_len The number of "byte" data elements to be processed. 818** 819** OUTPUTS: 820** 821** ldata Address to which the converted data is to be written. 822** 823** p_l_data_len NULL if fixed array is being marshalled. 824** The address to which the routine writes the 825** local data length. 826** 827** status The status of the operation. 828** Can be one of: 829** rpc_s_ok 830** rpc_ss_incompatible_codesets 831** or a status returned from a called routine. 832** 833** IMPLICIT INPUTS: none 834** 835** IMPLICIT OUTPUTS: none 836** 837** FUNCTION VALUE: void 838** 839** SIDE EFFECTS: none 840** 841**-- 842*/ 843 844PUBLIC void wchar_t_from_netcs 845( 846 rpc_binding_handle_t h, 847 unsigned32 tag, 848 idl_byte *wdata, 849 unsigned32 w_data_len, 850 unsigned32 l_storage_len, 851 wchar_t *ldata, 852 unsigned32 *p_l_data_len, 853 error_status_t *status 854) 855{ 856 char *current_codeset; 857 unsigned32 current_rgy_codeset; 858 idl_byte *byte_wdata; 859 idl_byte *t_byte_wdata; 860 size_t wdata_length; 861 size_t conv_length; 862 int i; 863 idl_byte *ldata_temp; 864 865 rpc_cs_method_eval_p_t method_p; 866 rpc_cs_tags_eval_p_t tags_p; 867 rpc_binding_rep_p_t bind_p; 868 869 bind_p = (rpc_binding_rep_p_t)h; 870 if (!RPC_BINDING_IS_SERVER (bind_p)) 871 { 872 switch (bind_p->cs_eval.key) 873 { 874 case RPC_CS_EVAL_METHOD: 875 method_p = &bind_p->cs_eval.tagged_union.method_key; 876 877 switch (method_p->method) 878 { 879 case RPC_EVAL_NO_CONVERSION: 880 case RPC_EVAL_SMIR_MODEL: 881 882 wdata_length = mbstowcs(ldata, (char *)wdata, (size_t)w_data_len); 883 if (wdata_length == -1) 884 /* Conversion error took place */ 885 *status = rpc_s_ss_invalid_char_input; 886 else 887 *status = rpc_s_ok; 888 889 if (p_l_data_len != NULL) 890 *p_l_data_len = wdata_length; 891 break; 892 893 case RPC_EVAL_CMIR_MODEL: 894 case RPC_EVAL_RMIR_MODEL: 895 case RPC_EVAL_INTERMEDIATE_MODEL: 896 case RPC_EVAL_UNIVERSAL_MODEL: 897 898 RPC_MEM_ALLOC ( 899 byte_wdata, 900 unsigned_char_p_t, 901 w_data_len, 902 RPC_C_MEM_STRING, 903 RPC_C_MEM_WAITOK); 904 905 /* initialize the buffer */ 906 t_byte_wdata = byte_wdata; 907 i = l_storage_len; 908 while (i--) 909 *t_byte_wdata++ = L'\0'; 910 911 stub_conversion ( 912 h, 913 RPC_BINDING_IS_SERVER (bind_p), 914 tag, 915 method_p->tags.client_tag, 916 wdata, 917 w_data_len, 918 byte_wdata, /* ldata, */ 919 (unsigned32 *)&wdata_length, /* p_l_data_len,*/ 920 status ); 921 922 wdata_length = mbstowcs(ldata, (char *)byte_wdata, (size_t)w_data_len); 923 if (wdata_length == -1) 924 /* Conversion error took place */ 925 *status = rpc_s_ss_invalid_char_input; 926 else 927 { 928 if (p_l_data_len != NULL) 929 *p_l_data_len = wdata_length; 930 931 *status = rpc_s_ok; 932 } 933 934 RPC_MEM_FREE(byte_wdata, RPC_C_MEM_STRING); 935 936 break; 937 938 default: 939 *status = rpc_s_ss_incompatible_codesets; 940 break; 941 942 } 943 break; 944 945 case RPC_CS_EVAL_TAGS: 946 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 947 948 if (tag == tags_p->client_tag) 949 /* No conversion required */ 950 { 951 wdata_length = mbstowcs(ldata, (char *)wdata, (size_t)w_data_len); 952 if (wdata_length == -1) 953 /* Conversion error took place */ 954 *status = rpc_s_ss_invalid_char_input; 955 else 956 *status = rpc_s_ok; 957 958 if (p_l_data_len != NULL) 959 *p_l_data_len = wdata_length; 960 } 961 else 962 { 963 RPC_MEM_ALLOC ( 964 byte_wdata, 965 unsigned_char_p_t, 966 w_data_len, 967 RPC_C_MEM_STRING, 968 RPC_C_MEM_WAITOK); 969 970 /* initialize the buffer */ 971 t_byte_wdata = byte_wdata; 972 i = w_data_len; 973 while (i--) 974 *t_byte_wdata++ = L'\0'; 975 976 stub_conversion ( 977 h, 978 RPC_BINDING_IS_SERVER (bind_p), 979 tag, 980 tags_p->client_tag, 981 wdata, 982 w_data_len, 983 byte_wdata, /* ldata, */ 984 (unsigned32 *)&wdata_length, /* p_l_data_len,*/ 985 status ); 986 987 wdata_length = mbstowcs(ldata, (char *)byte_wdata, (size_t)w_data_len); 988 if (wdata_length == -1) 989 /* Conversion error took place */ 990 *status = rpc_s_ss_invalid_char_input; 991 else 992 { 993 if (p_l_data_len != NULL) 994 *p_l_data_len = wdata_length; 995 996 *status = rpc_s_ok; 997 } 998 999 RPC_MEM_FREE(byte_wdata, RPC_C_MEM_STRING); 1000 1001 } 1002 break; 1003 1004 default: 1005 *status = rpc_s_ss_incompatible_codesets; 1006 break; 1007 } 1008 } 1009 else /* server side */ 1010 { 1011 /* 1012 * Get the code set info from the current locale. 1013 */ 1014 current_codeset = nl_langinfo(CODESET); 1015 dce_cs_loc_to_rgy( 1016 (unsigned_char_p_t)current_codeset, 1017 ¤t_rgy_codeset, 1018 NULL, NULL, 1019 status); 1020 1021 if (*status != dce_cs_c_ok) 1022 { 1023 /* codeset registry error */ 1024 *status = rpc_s_ok; 1025 return; 1026 } 1027 /* 1028 * Determine the conversion type. 1029 */ 1030 if (tag == current_rgy_codeset) 1031 /* No conversion required */ 1032 { 1033 wdata_length = mbstowcs(ldata, (char *)wdata, (size_t)w_data_len); 1034 if (wdata_length == -1) 1035 /* Conversion error took place */ 1036 *status = rpc_s_ss_invalid_char_input; 1037 else 1038 { 1039 if (p_l_data_len != NULL) 1040 *p_l_data_len = wdata_length; 1041 1042 *status = rpc_s_ok; 1043 } 1044 } 1045 else 1046 { 1047 RPC_MEM_ALLOC ( 1048 byte_wdata, 1049 unsigned_char_p_t, 1050 w_data_len, 1051 RPC_C_MEM_STRING, 1052 RPC_C_MEM_WAITOK); 1053 1054 /* initialize the buffer */ 1055 t_byte_wdata = byte_wdata; 1056 i = w_data_len; 1057 while (i--) 1058 *t_byte_wdata++ = L'\0'; 1059 1060 stub_conversion ( 1061 h, 1062 RPC_BINDING_IS_SERVER (bind_p), 1063 tag, 1064 current_rgy_codeset, 1065 wdata, 1066 w_data_len, 1067 byte_wdata, /* ldata, */ 1068 (unsigned32 *)&wdata_length, /* p_l_data_len,*/ 1069 status ); 1070 1071 wdata_length = mbstowcs(ldata, (char *)byte_wdata, (size_t)w_data_len); 1072 if (wdata_length == -1) 1073 /* Conversion error took place */ 1074 *status = rpc_s_ss_invalid_char_input; 1075 else 1076 { 1077 if (p_l_data_len != NULL) 1078 *p_l_data_len = wdata_length; 1079 1080 *status = rpc_s_ok; 1081 } 1082 1083 RPC_MEM_FREE(byte_wdata, RPC_C_MEM_STRING); 1084 } 1085 } 1086 return; 1087} 1088 1089 1090/* 1091**++ 1092** ROUTINE NAME: cs_byte_net_size 1093** 1094** SCOPE: PUBLIC - declared in dce/codesets_stub.h 1095** 1096** DESCRIPTION: 1097** 1098** Calculate the necessary buffer size for code set converesion, based on 1099** the information from a binding handle, tag, and local storage size. 1100** 1101** INPUTS: 1102** 1103** h Binding handle 1104** 1105** tag Identifies the code set that will be used on the wire. 1106** When the caller is a client stub, this is cs_stag value. 1107** When the caller is a server stub, this is cs_rtag value. 1108** 1109** l_storage_len The size, in units of byte, of the local storage 1110** allocated for the I-char data. This is the local value 1111** of the size_is variable for the array. 1112** 1113** OUTPUTS: 1114** 1115** p_convert_type Indicate whether data conversion is necessary. 1116** In case of idl_cs_in_place_convert, l_storage_len 1117** is assumed to be sufficient for the buffer size. 1118** 1119** p_w_storage_len NULL if fixed or varying array is being marshalled. 1120** When conformant or conformant varying array is being 1121** marshalled, and p_convert_type is idl_cs_new_buffer 1122** convert, this is the storage size in units of idl_byte. 1123** 1124** status The status of the operation. 1125** Can be one of: 1126** rpc_s_ok 1127** rpc_ss_incompatible_codesets 1128** or a status returned from a called routine. 1129** 1130** IMPLICIT INPUTS: none 1131** 1132** IMPLICIT OUTPUTS: none 1133** 1134** FUNCTION VALUE: void 1135** 1136** SIDE EFFECTS: none 1137** 1138**-- 1139*/ 1140 1141PUBLIC void cs_byte_net_size 1142( 1143 rpc_binding_handle_t h, 1144 unsigned32 tag, /* wire encoding */ 1145 unsigned32 l_storage_len, 1146 idl_cs_convert_t *p_convert_type, 1147 unsigned32 *p_w_storage_len, 1148 error_status_t *status 1149) 1150{ 1151 char *current_codeset; 1152 unsigned32 current_rgy_codeset; 1153 unsigned16 stag_bytes; 1154 unsigned16 client_bytes; 1155 1156 rpc_cs_method_eval_p_t method_p; 1157 rpc_cs_tags_eval_p_t tags_p; 1158 rpc_binding_rep_p_t bind_p; 1159 1160 bind_p = (rpc_binding_rep_p_t)h; 1161 if (!RPC_BINDING_IS_SERVER (bind_p)) 1162 { 1163 switch (bind_p->cs_eval.key) 1164 { 1165 case RPC_CS_EVAL_METHOD: 1166 method_p = &bind_p->cs_eval.tagged_union.method_key; 1167 1168 if (method_p->tags.type_handle != NULL) 1169 { 1170 if ((idl_cs_convert_t)method_p->tags.type_handle 1171 == idl_cs_no_convert || 1172 (idl_cs_convert_t)method_p->tags.type_handle 1173 == idl_cs_in_place_convert) 1174 { 1175 1176 *p_convert_type = (idl_cs_convert_t) 1177 method_p->tags.type_handle; 1178 if (p_w_storage_len != NULL) 1179 *p_w_storage_len = l_storage_len; 1180 *status = rpc_s_ok; 1181 1182 } 1183 else if ((idl_cs_convert_t) 1184 method_p->tags.type_handle 1185 == idl_cs_new_buffer_convert) 1186 { 1187 *p_convert_type = (idl_cs_convert_t) 1188 method_p->tags.type_handle; 1189 1190 if (p_w_storage_len != NULL) 1191 *p_w_storage_len 1192 = l_storage_len * 1193 method_p->tags.stag_max_bytes; 1194 *status = rpc_s_ok; 1195 1196 } 1197 } 1198 else 1199 { 1200 switch (method_p->method) 1201 { 1202 case RPC_EVAL_NO_CONVERSION: 1203 case RPC_EVAL_RMIR_MODEL: 1204 case RPC_EVAL_SMIR_MODEL: 1205 *p_convert_type = idl_cs_no_convert; 1206 if (p_w_storage_len != NULL) 1207 *p_w_storage_len = l_storage_len; 1208 1209 if (method_p->fixed) 1210 method_p->tags.type_handle 1211 = (rpc_ns_handle_t)*p_convert_type; 1212 1213 *status = rpc_s_ok; 1214 break; 1215 1216 case RPC_EVAL_CMIR_MODEL: 1217 case RPC_EVAL_INTERMEDIATE_MODEL: 1218 case RPC_EVAL_UNIVERSAL_MODEL: 1219 1220 if ((method_p->fixed) && 1221 (method_p->tags.stag_max_bytes == 1222 method_p->tags.client_max_bytes)) 1223 { 1224 *p_convert_type = 1225 idl_cs_in_place_convert; 1226 if (p_w_storage_len != NULL) 1227 *p_w_storage_len = l_storage_len; 1228 } 1229 else if ( method_p->tags.stag_max_bytes == 1230 method_p->client->codesets[0].c_max_bytes) 1231 { 1232 *p_convert_type = 1233 idl_cs_in_place_convert; 1234 if (p_w_storage_len != NULL) 1235 *p_w_storage_len = l_storage_len; 1236 } 1237 else 1238 { 1239 *p_convert_type 1240 = idl_cs_new_buffer_convert; 1241 if (p_w_storage_len != NULL) 1242 *p_w_storage_len = l_storage_len 1243 * method_p->tags.stag_max_bytes; 1244 } 1245 *status = rpc_s_ok; 1246 1247 if (method_p->fixed) 1248 method_p->tags.type_handle 1249 = (rpc_ns_handle_t)*p_convert_type; 1250 break; 1251 1252 default: 1253 *status = rpc_s_ss_incompatible_codesets; 1254 break; 1255 1256 } 1257 } 1258 break; 1259 1260 case RPC_CS_EVAL_TAGS: 1261 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 1262 1263 if (tags_p->type_handle != NULL) 1264 { 1265 if ((idl_cs_convert_t)tags_p->type_handle 1266 == idl_cs_no_convert || 1267 (idl_cs_convert_t)tags_p->type_handle 1268 == idl_cs_in_place_convert) 1269 { 1270 *p_convert_type = (idl_cs_convert_t) 1271 tags_p->type_handle; 1272 1273 if (p_w_storage_len != NULL) 1274 *p_w_storage_len = l_storage_len; 1275 *status = rpc_s_ok; 1276 1277 } 1278 else if ((idl_cs_convert_t)tags_p->type_handle 1279 == idl_cs_new_buffer_convert) 1280 { 1281 *p_convert_type = (idl_cs_convert_t) 1282 tags_p->type_handle; 1283 1284 if (p_w_storage_len != NULL) 1285 *p_w_storage_len = 1286 l_storage_len * tags_p->stag_max_bytes; 1287 1288 *status = rpc_s_ok; 1289 } 1290 } 1291 else 1292 { 1293 /* 1294 * Determine the conversion type. 1295 */ 1296 if (tag == tags_p->client_tag) 1297 /* No conversion required */ 1298 { 1299 *p_convert_type = idl_cs_no_convert; 1300 if (p_w_storage_len != NULL) 1301 *p_w_storage_len = l_storage_len; 1302 } 1303 else 1304 { 1305 if (tags_p->stag_max_bytes == 1306 tags_p->client_max_bytes) 1307 1308 { 1309 *p_convert_type = 1310 idl_cs_in_place_convert; 1311 1312 if (p_w_storage_len != NULL) 1313 *p_w_storage_len = l_storage_len; 1314 } 1315 else 1316 { 1317 *p_convert_type = 1318 idl_cs_new_buffer_convert; 1319 if (p_w_storage_len != NULL) 1320 *p_w_storage_len = 1321 l_storage_len * tags_p->stag_max_bytes; 1322 } 1323 1324 } 1325 *status = rpc_s_ok; 1326 1327 tags_p->type_handle = (rpc_ns_handle_t) 1328 *p_convert_type; 1329 } 1330 break; 1331 1332 default: 1333 *status = rpc_s_ss_incompatible_codesets; 1334 break; 1335 } 1336 } 1337 else /* Server side */ 1338 { 1339 /* 1340 * Get the code set info from the current locale. 1341 */ 1342 current_codeset = nl_langinfo(CODESET); 1343 dce_cs_loc_to_rgy( 1344 (unsigned_char_p_t)current_codeset, 1345 ¤t_rgy_codeset, 1346 NULL, NULL, 1347 status); 1348 1349 if (*status != dce_cs_c_ok) 1350 { 1351 /* codeset registry error */ 1352 *status = rpc_s_ok; 1353 return; 1354 } 1355 1356 /* 1357 * Determine the conversion type. 1358 */ 1359 if (tag == current_rgy_codeset) 1360 /* No conversion required */ 1361 { 1362 *p_convert_type = idl_cs_no_convert; 1363 if (p_w_storage_len != NULL) 1364 *p_w_storage_len = l_storage_len; 1365 1366 *status = rpc_s_ok; 1367 } 1368 else 1369 { 1370 rpc_rgy_get_max_bytes ( 1371 tag, 1372 &stag_bytes, 1373 status ); 1374 1375 if (*status != rpc_s_ok) 1376 return; 1377 1378 rpc_rgy_get_max_bytes ( 1379 current_rgy_codeset, 1380 &client_bytes, 1381 status ); 1382 1383 if (*status != rpc_s_ok) 1384 return; 1385 1386 if (stag_bytes == client_bytes) 1387 { 1388 *p_convert_type = idl_cs_in_place_convert; 1389 1390 if (p_w_storage_len != NULL) 1391 *p_w_storage_len = l_storage_len; 1392 } 1393 else 1394 { 1395 *p_convert_type = idl_cs_new_buffer_convert; 1396 1397 if (p_w_storage_len != NULL) 1398 *p_w_storage_len = l_storage_len * stag_bytes; 1399 } 1400 1401 *status = rpc_s_ok; 1402 } 1403 } 1404 return; 1405} 1406 1407 1408/* 1409**++ 1410** ROUTINE NAME: wchar_t_net_size 1411** 1412** SCOPE: PUBLIC - declared in dce/codesets_stub.h 1413** 1414** DESCRIPTION: 1415** 1416** Calculate the necessary buffer size for code set converesion, based on 1417** the information from a binding handle, tag, and local storage size. 1418** 1419** INPUTS: 1420** 1421** h Binding handle 1422** 1423** tag Identifies the code set that will be used on the wire. 1424** When the caller is a client stub, this is cs_stag value. 1425** When the caller is a server stub, this is cs_rtag value. 1426** 1427** l_storage_len The size, in units of byte, of the local storage 1428** allocated for the I-char data. This is the local value 1429** of the size_is variable for the array. 1430** 1431** OUTPUTS: 1432** 1433** p_convert_type Indicate whether data conversion is necessary. 1434** In case of idl_cs_in_place_convert, l_storage_len 1435** is assumed to be sufficient for the buffer size. 1436** 1437** p_w_storage_len NULL if fixed or varying array is being marshalled. 1438** When conformant or conformant varying array is being 1439** marshalled, and p_convert_type is idl_cs_new_buffer 1440** convert, this is the storage size in units of idl_byte. 1441** 1442** status The status of the operation. 1443** Can be one of: 1444** rpc_s_ok 1445** rpc_ss_incompatible_codesets 1446** or a status returned from a called routine. 1447** 1448** IMPLICIT INPUTS: none 1449** 1450** IMPLICIT OUTPUTS: none 1451** 1452** FUNCTION VALUE: void 1453** 1454** SIDE EFFECTS: none 1455** 1456**-- 1457*/ 1458 1459/* 1460** We calculate the buffer size by multiplying the number of wchar_t by 1461** the maximum bytes of wire encoding. 1462*/ 1463 1464PUBLIC void wchar_t_net_size 1465( 1466 rpc_binding_handle_t h, 1467 unsigned32 tag, /* wire encoding */ 1468 unsigned32 l_storage_len, /* wchar_t length */ 1469 idl_cs_convert_t *p_convert_type, 1470 unsigned32 *p_w_storage_len, 1471 error_status_t *status 1472) 1473{ 1474 char *current_codeset; 1475 unsigned32 current_rgy_codeset; 1476 unsigned16 stag_bytes; 1477 unsigned16 client_bytes; 1478 1479 rpc_cs_method_eval_p_t method_p; 1480 rpc_cs_tags_eval_p_t tags_p; 1481 rpc_binding_rep_p_t bind_p; 1482 1483 bind_p = (rpc_binding_rep_p_t)h; 1484 if (!RPC_BINDING_IS_SERVER (bind_p)) 1485 { 1486 switch (bind_p->cs_eval.key) 1487 { 1488 case RPC_CS_EVAL_METHOD: 1489 method_p = &bind_p->cs_eval.tagged_union.method_key; 1490 1491 if (method_p->tags.type_handle != NULL) 1492 { 1493 *p_convert_type = (idl_cs_convert_t) 1494 method_p->tags.type_handle; 1495 1496 if (p_w_storage_len != NULL) 1497 *p_w_storage_len = l_storage_len 1498 * sizeof(wchar_t); 1499 *status = rpc_s_ok; 1500 1501 } 1502 else 1503 { 1504 switch (method_p->method) 1505 { 1506 case RPC_EVAL_NO_CONVERSION: 1507 case RPC_EVAL_RMIR_MODEL: 1508 case RPC_EVAL_SMIR_MODEL: 1509 case RPC_EVAL_CMIR_MODEL: 1510 case RPC_EVAL_INTERMEDIATE_MODEL: 1511 case RPC_EVAL_UNIVERSAL_MODEL: 1512 1513 *p_convert_type = idl_cs_new_buffer_convert; 1514 1515 if (p_w_storage_len != NULL) 1516 *p_w_storage_len = l_storage_len 1517 * sizeof(wchar_t); 1518 1519 *status = rpc_s_ok; 1520 1521 if (method_p->fixed) 1522 method_p->tags.type_handle 1523 = (rpc_ns_handle_t)*p_convert_type; 1524 break; 1525 1526 default: 1527 *status = rpc_s_ss_incompatible_codesets; 1528 break; 1529 1530 } 1531 } 1532 break; 1533 1534 case RPC_CS_EVAL_TAGS: 1535 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 1536 1537 if (tags_p->type_handle != NULL) 1538 { 1539 *p_convert_type = (idl_cs_convert_t)tags_p->type_handle; 1540 1541 if (p_w_storage_len != NULL) 1542 *p_w_storage_len = l_storage_len 1543 * sizeof(wchar_t); 1544 1545 *status = rpc_s_ok; 1546 } 1547 else 1548 { 1549 /* 1550 * Determine the conversion type. 1551 */ 1552 *p_convert_type = idl_cs_new_buffer_convert; 1553 if (p_w_storage_len != NULL) 1554 *p_w_storage_len = l_storage_len * sizeof(wchar_t); 1555 *status = rpc_s_ok; 1556 1557 tags_p->type_handle = 1558 (rpc_ns_handle_t)*p_convert_type; 1559 } 1560 break; 1561 1562 default: 1563 *status = rpc_s_ss_incompatible_codesets; 1564 break; 1565 } 1566 } 1567 else /* Server side */ 1568 { 1569 *p_convert_type = idl_cs_new_buffer_convert; 1570 1571 if (p_w_storage_len != NULL) 1572 *p_w_storage_len = l_storage_len * sizeof(wchar_t); 1573 1574 *status = rpc_s_ok; 1575 } 1576 return; 1577} 1578 1579 1580/* 1581**++ 1582** ROUTINE NAME: cs_byte_local_size 1583** 1584** SCOPE: PUBLIC - declared in dce/codesets_stub.h 1585** 1586** DESCRIPTION: 1587** 1588** Calculate the necessary buffer size for code set converesion, based on 1589** the information from a binding handle, tag, and on-the_wire storage size. 1590** 1591** INPUTS: 1592** 1593** h Binding handle 1594** 1595** tag Identifies the code set that will be used on the wire. 1596** When the caller is a client stub, this is cs_stag value. 1597** When the caller is a server stub, this is cs_rtag value. 1598** 1599** w_storage_len The size, in units of byte, of the on-the_wire storage 1600** allocated for the I-char data. 1601** 1602** OUTPUTS: 1603** 1604** p_convert_type Indicate whether data conversion is necessary. 1605** In case of idl_cs_in_place_convert, w_storage_len 1606** is assumed to be sufficient for the buffer size. 1607** 1608** p_l_storage_len NULL if fixed or varying array is being marshalled. 1609** When conformant or conformant varying array is being 1610** marshalled, and p_convert_type is idl_cs_new_buffer 1611** convert, this is the storage size in units of idl_byte. 1612** 1613** status The status of the operation. 1614** Can be one of: 1615** rpc_s_ok 1616** rpc_ss_incompatible_codesets 1617** or a status returned from a called routine. 1618** 1619** IMPLICIT INPUTS: none 1620** 1621** IMPLICIT OUTPUTS: none 1622** 1623** FUNCTION VALUE: void 1624** 1625** SIDE EFFECTS: none 1626** 1627**-- 1628*/ 1629 1630PUBLIC void cs_byte_local_size 1631( 1632 rpc_binding_handle_t h, 1633 unsigned32 tag, /* wire encoding */ 1634 unsigned32 w_storage_len, 1635 idl_cs_convert_t *p_convert_type, 1636 unsigned32 *p_l_storage_len, 1637 error_status_t *status 1638) 1639{ 1640 char *current_codeset; 1641 unsigned32 current_rgy_codeset; 1642 unsigned16 stag_bytes; 1643 unsigned16 client_bytes; 1644 1645 rpc_cs_method_eval_p_t method_p; 1646 rpc_cs_tags_eval_p_t tags_p; 1647 rpc_binding_rep_p_t bind_p; 1648 1649 bind_p = (rpc_binding_rep_p_t)h; 1650 if (!RPC_BINDING_IS_SERVER (bind_p)) 1651 { 1652 switch (bind_p->cs_eval.key) 1653 { 1654 case RPC_CS_EVAL_METHOD: 1655 method_p = &bind_p->cs_eval.tagged_union.method_key; 1656 1657 if (method_p->tags.type_handle != NULL) 1658 { 1659 if ((idl_cs_convert_t)method_p->tags.type_handle 1660 == idl_cs_no_convert || 1661 (idl_cs_convert_t)method_p->tags.type_handle 1662 == idl_cs_in_place_convert) 1663 { 1664 1665 *p_convert_type = (idl_cs_convert_t) 1666 method_p->tags.type_handle; 1667 1668 if (p_l_storage_len != NULL) 1669 *p_l_storage_len = w_storage_len; 1670 *status = rpc_s_ok; 1671 1672 } 1673 else if ((idl_cs_convert_t)method_p->tags.type_handle 1674 == idl_cs_new_buffer_convert) 1675 { 1676 *p_convert_type = (idl_cs_convert_t) 1677 method_p->tags.type_handle; 1678 1679 if (p_l_storage_len != NULL) 1680 *p_l_storage_len = w_storage_len 1681 * method_p->tags.stag_max_bytes; 1682 1683 *status = rpc_s_ok; 1684 1685 } 1686 } 1687 else 1688 { 1689 switch (method_p->method) 1690 { 1691 case RPC_EVAL_NO_CONVERSION: 1692 case RPC_EVAL_SMIR_MODEL: 1693 case RPC_EVAL_CMIR_MODEL: 1694 case RPC_EVAL_RMIR_MODEL: 1695 case RPC_EVAL_INTERMEDIATE_MODEL: 1696 case RPC_EVAL_UNIVERSAL_MODEL: 1697 1698 if ((method_p->fixed) && 1699 (method_p->tags.stag_max_bytes == 1700 method_p->tags.client_max_bytes)) 1701 { 1702 *p_convert_type = idl_cs_in_place_convert; 1703 1704 if (p_l_storage_len != NULL) 1705 *p_l_storage_len = w_storage_len; 1706 } 1707 else if (method_p->tags.stag_max_bytes == 1708 method_p->client->codesets[0].c_max_bytes) 1709 { 1710 *p_convert_type = idl_cs_in_place_convert; 1711 1712 if (p_l_storage_len != NULL) 1713 *p_l_storage_len = w_storage_len; 1714 } 1715 else 1716 { 1717 *p_convert_type = idl_cs_new_buffer_convert; 1718 if (p_l_storage_len != NULL) 1719 *p_l_storage_len = w_storage_len 1720 * method_p->tags.stag_max_bytes; 1721 } 1722 *status = rpc_s_ok; 1723 1724 if (method_p->fixed) 1725 method_p->tags.type_handle = 1726 (rpc_ns_handle_t)*p_convert_type; 1727 break; 1728 1729 default: 1730 *status = rpc_s_ss_incompatible_codesets; 1731 break; 1732 1733 } 1734 } 1735 break; 1736 1737 case RPC_CS_EVAL_TAGS: 1738 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 1739 1740 if (tags_p->type_handle != NULL) 1741 { 1742 if ((idl_cs_convert_t)tags_p->type_handle 1743 == idl_cs_no_convert || 1744 (idl_cs_convert_t)tags_p->type_handle 1745 == idl_cs_in_place_convert) 1746 { 1747 *p_convert_type = 1748 (idl_cs_convert_t)tags_p->type_handle; 1749 if (p_l_storage_len != NULL) 1750 *p_l_storage_len = w_storage_len; 1751 *status = rpc_s_ok; 1752 1753 } 1754 else if ((idl_cs_convert_t)tags_p->type_handle 1755 == idl_cs_new_buffer_convert) 1756 { 1757 *p_convert_type = 1758 (idl_cs_convert_t)tags_p->type_handle; 1759 if (p_l_storage_len != NULL) 1760 *p_l_storage_len = 1761 w_storage_len * tags_p->stag_max_bytes; 1762 *status = rpc_s_ok; 1763 } 1764 } 1765 else 1766 { 1767 /* 1768 * Determine the conversion type. 1769 */ 1770 if (tag == tags_p->client_tag) 1771 /* No conversion required */ 1772 { 1773 *p_convert_type = idl_cs_no_convert; 1774 if (p_l_storage_len != NULL) 1775 *p_l_storage_len = w_storage_len; 1776 } 1777 else 1778 { 1779 if (tags_p->stag_max_bytes == 1780 tags_p->client_max_bytes) 1781 { 1782 *p_convert_type 1783 = idl_cs_in_place_convert; 1784 1785 if (p_l_storage_len != NULL) 1786 *p_l_storage_len = w_storage_len; 1787 } 1788 else 1789 { 1790 *p_convert_type 1791 = idl_cs_new_buffer_convert; 1792 1793 if (p_l_storage_len != NULL) 1794 *p_l_storage_len 1795 = w_storage_len * tags_p->stag_max_bytes; 1796 } 1797 1798 } 1799 *status = rpc_s_ok; 1800 1801 tags_p->type_handle 1802 = (rpc_ns_handle_t) *p_convert_type; 1803 } 1804 break; 1805 1806 default: 1807 *status = rpc_s_ss_incompatible_codesets; 1808 break; 1809 } 1810 } 1811 else /* Server side */ 1812 { 1813 /* 1814 * Get the code set info from the current locale. 1815 */ 1816 current_codeset = nl_langinfo(CODESET); 1817 dce_cs_loc_to_rgy( 1818 (unsigned_char_p_t)current_codeset, 1819 ¤t_rgy_codeset, 1820 NULL, NULL, 1821 status); 1822 1823 if (*status != dce_cs_c_ok) 1824 { 1825 /* codeset registry error */ 1826 *status = rpc_s_ok; 1827 return; 1828 } 1829 1830 /* 1831 * Determine the conversion type. 1832 */ 1833 if (tag == current_rgy_codeset) 1834 /* No conversion required */ 1835 { 1836 *p_convert_type = idl_cs_no_convert; 1837 1838 if (p_l_storage_len != NULL) 1839 *p_l_storage_len = w_storage_len; 1840 1841 *status = rpc_s_ok; 1842 } 1843 else 1844 { 1845 rpc_rgy_get_max_bytes ( 1846 tag, 1847 &stag_bytes, 1848 status ); 1849 1850 if (*status != rpc_s_ok) 1851 return; 1852 1853 rpc_rgy_get_max_bytes ( 1854 current_rgy_codeset, 1855 &client_bytes, 1856 status ); 1857 1858 if (*status != rpc_s_ok) 1859 return; 1860 1861 if (stag_bytes == client_bytes) 1862 { 1863 *p_convert_type = idl_cs_in_place_convert; 1864 1865 if (p_l_storage_len != NULL) 1866 *p_l_storage_len = w_storage_len; 1867 } 1868 else 1869 { 1870 *p_convert_type = idl_cs_new_buffer_convert; 1871 1872 if (p_l_storage_len != NULL) 1873 *p_l_storage_len = w_storage_len * stag_bytes; 1874 } 1875 1876 *status = rpc_s_ok; 1877 } 1878 } 1879 return; 1880} 1881 1882 1883/* 1884**++ 1885** ROUTINE NAME: wchar_t_local_size 1886** 1887** SCOPE: PUBLIC - declared in dce/codesets_stub.h 1888** 1889** DESCRIPTION: 1890** 1891** Calculate the necessary buffer size for code set converesion, based on 1892** the information from a binding handle, tag, and on-the_wire storage size. 1893** 1894** INPUTS: 1895** 1896** h Binding handle 1897** 1898** tag Identifies the code set that will be used on the wire. 1899** When the caller is a client stub, this is cs_stag value. 1900** When the caller is a server stub, this is cs_rtag value. 1901** 1902** w_storage_len The size, in units of byte, of the on-the_wire storage 1903** allocated for the I-char data. 1904** 1905** OUTPUTS: 1906** 1907** p_convert_type Indicate whether data conversion is necessary. 1908** In case of idl_cs_in_place_convert, w_storage_len 1909** is assumed to be sufficient for the buffer size. 1910** 1911** p_l_storage_len NULL if fixed or varying array is being marshalled. 1912** When conformant or conformant varying array is being 1913** marshalled, and p_convert_type is idl_cs_new_buffer 1914** convert, this is the storage size in units of idl_byte. 1915** 1916** status The status of the operation. 1917** Can be one of: 1918** rpc_s_ok 1919** rpc_ss_incompatible_codesets 1920** or a status returned from a called routine. 1921** 1922** IMPLICIT INPUTS: none 1923** 1924** IMPLICIT OUTPUTS: none 1925** 1926** FUNCTION VALUE: void 1927** 1928** SIDE EFFECTS: none 1929** 1930**-- 1931*/ 1932 1933PUBLIC void wchar_t_local_size 1934( 1935 rpc_binding_handle_t h, 1936 unsigned32 tag, /* wire encoding */ 1937 unsigned32 w_storage_len, 1938 idl_cs_convert_t *p_convert_type, 1939 unsigned32 *p_l_storage_len, /* wchar_t size */ 1940 error_status_t *status 1941) 1942{ 1943 char *current_codeset; 1944 unsigned32 current_rgy_codeset; 1945 unsigned16 stag_bytes; 1946 unsigned16 client_bytes; 1947 1948 rpc_cs_method_eval_p_t method_p; 1949 rpc_cs_tags_eval_p_t tags_p; 1950 rpc_binding_rep_p_t bind_p; 1951 1952 bind_p = (rpc_binding_rep_p_t)h; 1953 if (!RPC_BINDING_IS_SERVER (bind_p)) 1954 { 1955 switch (bind_p->cs_eval.key) 1956 { 1957 case RPC_CS_EVAL_METHOD: 1958 method_p = &bind_p->cs_eval.tagged_union.method_key; 1959 1960 if (method_p->tags.type_handle != NULL) 1961 { 1962 *p_convert_type = (idl_cs_convert_t) 1963 method_p->tags.type_handle; 1964 1965 if (p_l_storage_len != NULL) 1966 *p_l_storage_len = w_storage_len 1967 / sizeof(wchar_t); 1968 1969 *status = rpc_s_ok; 1970 } 1971 else 1972 { 1973 switch (method_p->method) 1974 { 1975 case RPC_EVAL_NO_CONVERSION: 1976 case RPC_EVAL_SMIR_MODEL: 1977 case RPC_EVAL_CMIR_MODEL: 1978 case RPC_EVAL_RMIR_MODEL: 1979 case RPC_EVAL_INTERMEDIATE_MODEL: 1980 case RPC_EVAL_UNIVERSAL_MODEL: 1981 1982 *p_convert_type = idl_cs_new_buffer_convert; 1983 if (p_l_storage_len != NULL) 1984 *p_l_storage_len = 1985 w_storage_len / sizeof(wchar_t); 1986 1987 *status = rpc_s_ok; 1988 1989 if (method_p->fixed) 1990 method_p->tags.type_handle = 1991 (rpc_ns_handle_t)*p_convert_type; 1992 break; 1993 1994 default: 1995 *status = rpc_s_ss_incompatible_codesets; 1996 break; 1997 1998 } 1999 } 2000 break; 2001 2002 case RPC_CS_EVAL_TAGS: 2003 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 2004 2005 if (tags_p->type_handle != NULL) 2006 { 2007 *p_convert_type = 2008 (idl_cs_convert_t)tags_p->type_handle; 2009 2010 if (p_l_storage_len != NULL) 2011 *p_l_storage_len = w_storage_len 2012 / sizeof(wchar_t); 2013 2014 *status = rpc_s_ok; 2015 } 2016 else 2017 { 2018 *p_convert_type = idl_cs_new_buffer_convert; 2019 2020 if (p_l_storage_len != NULL) 2021 *p_l_storage_len = w_storage_len 2022 / sizeof(wchar_t); 2023 2024 *status = rpc_s_ok; 2025 2026 tags_p->type_handle 2027 = (rpc_ns_handle_t) *p_convert_type; 2028 } 2029 break; 2030 2031 default: 2032 *status = rpc_s_ss_incompatible_codesets; 2033 break; 2034 } 2035 } 2036 else /* Server side */ 2037 { 2038 *p_convert_type = idl_cs_new_buffer_convert; 2039 2040 if (p_l_storage_len != NULL) 2041 *p_l_storage_len = w_storage_len / sizeof(wchar_t); 2042 2043 *status = rpc_s_ok; 2044 } 2045 return; 2046} 2047 2048 2049/* 2050**++ 2051** ROUTINE NAME: rpc_cs_get_tags 2052** 2053** SCOPE: PUBLIC - declared in rpc.idl 2054** 2055** DESCRIPTION: 2056** 2057** Select codeset conversion tags based on the binding handle 2058** 2059** INPUTS: 2060** 2061** h Binding handle 2062** 2063** server_side boolean input to indicate if the caller is a server stub 2064** 2065** OUTPUTS: 2066** 2067** p_stag tag to indicate the sending codeset by a client 2068** When the caller is a server stub, this is unused. 2069** 2070** p_drtag tag to indicate the desired received codeset. 2071** When the caller is a server stub, this is an input 2072** When the caller is a client stub, this is an output 2073** 2074** p_rtag tag to indicate the sending codeset by a server 2075** When the caller is a client stub, this is unused. 2076** 2077** status The status of the operation. 2078** Can be one of: 2079** rpc_s_ok 2080** rpc_ss_incompatible_codesets 2081** or a status returned from a called routine. 2082** 2083** IMPLICIT INPUTS: none 2084** 2085** IMPLICIT OUTPUTS: none 2086** 2087** FUNCTION VALUE: void 2088** 2089** SIDE EFFECTS: none 2090** 2091**-- 2092*/ 2093 2094PUBLIC void rpc_cs_get_tags 2095( 2096 rpc_binding_handle_t h, 2097 idl_boolean server_side, 2098 unsigned32 *p_stag, 2099 unsigned32 *p_drtag, 2100 unsigned32 *p_rtag, 2101 error_status_t *status 2102) 2103{ 2104 rpc_binding_rep_p_t bind_p; 2105 rpc_cs_method_eval_p_t method_p; 2106 rpc_cs_tags_eval_p_t tags_p; 2107 unsigned_char_t *entry_name; 2108 int i, j; 2109 rpc_codeset_mgmt_p_t client, server; 2110 int model_found, smir_true, cmir_true; 2111 long i_code; 2112 int i_max_bytes; 2113 error_status_t temp_status; 2114 2115 if (!server_side) 2116 { 2117 bind_p = (rpc_binding_rep_p_t)h; 2118 2119 if (bind_p->extended_bind_flag == RPC_C_BH_EXTENDED_CODESETS) 2120 { 2121 /* 2122 * Determine the data structure 2123 */ 2124 switch (bind_p->cs_eval.key) 2125 { 2126 case RPC_CS_EVAL_METHOD: 2127 method_p = &bind_p->cs_eval.tagged_union.method_key; 2128 2129 if (method_p->fixed) 2130 { 2131 *p_stag = method_p->tags.stag; 2132 *p_drtag = method_p->tags.drtag; 2133 } 2134 else 2135 { 2136 /* 2137 * We will evaluate code set I14Y here 2138 */ 2139 (*(method_p->cs_stub_eval_func))(p_stag, p_drtag, status); 2140 if (*status != rpc_s_ok) 2141 return; 2142 2143 method_p->tags.stag = *p_stag; 2144 method_p->tags.drtag = *p_drtag; 2145 2146 rpc_rgy_get_max_bytes ( 2147 *p_stag, 2148 &method_p->tags.stag_max_bytes, 2149 status 2150 ); 2151 2152 if (*status != rpc_s_ok) 2153 return; 2154 2155 /* Get client's supported code sets */ 2156 rpc_rgy_get_codesets ( 2157 &client, 2158 status ); 2159 2160 if (*status != rpc_s_ok) 2161 return; 2162 2163 method_p->tags.client_tag = client->codesets[0].c_set; 2164 method_p->tags.client_max_bytes = client->codesets[0].c_max_bytes; 2165 method_p->tags.type_handle = NULL; 2166 } 2167 2168 break; 2169 2170 case RPC_CS_EVAL_TAGS: 2171 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 2172 2173 *p_stag = tags_p->stag; 2174 *p_drtag = tags_p->drtag; 2175 2176 break; 2177 2178 default: 2179 *status = rpc_s_ss_invalid_codeset_tag; 2180 } 2181 2182 *status = rpc_s_ok; 2183 } 2184 else 2185 { 2186 /* No evaluation is done so far, so we try to figure 2187 * out if server and client are compatible 2188 */ 2189 2190 /* Get the client's supported code sets */ 2191 rpc_rgy_get_codesets ( 2192 &client, 2193 status ); 2194 2195 if (*status != rpc_s_ok) 2196 return; 2197 2198 /* Get the name of server entry in NSI */ 2199 rpc_ns_binding_inq_entry_name ( 2200 h, 2201 rpc_c_ns_syntax_default, 2202 &entry_name, 2203 status ); 2204 2205 if (*status != rpc_s_ok) 2206 { 2207 rpc_ns_mgmt_free_codesets(&client, &temp_status); 2208 return; 2209 } 2210 2211 /* Get the server's supported code sets from NSI */ 2212 rpc_ns_mgmt_read_codesets ( 2213 rpc_c_ns_syntax_default, 2214 entry_name, 2215 &server, 2216 status ); 2217 2218 if (*status != rpc_s_ok) 2219 { 2220 rpc_ns_mgmt_free_codesets(&client, &temp_status); 2221 return; 2222 } 2223 2224 /* Start evaluation */ 2225 if (client->codesets[0].c_set == server->codesets[0].c_set) 2226 { 2227 /* client and server are using the same code set */ 2228 *p_stag = client->codesets[0].c_set; 2229 *p_drtag = server->codesets[0].c_set; 2230 2231 tags_p->stag = *p_stag; 2232 tags_p->drtag = *p_drtag; 2233 tags_p->stag_max_bytes = client->codesets[0].c_max_bytes; 2234 tags_p->client_tag = client->codesets[0].c_set; 2235 tags_p->client_max_bytes = client->codesets[0].c_max_bytes; 2236 tags_p->type_handle = NULL; 2237 } 2238 else 2239 { 2240 /* Check character set compatibility first */ 2241 rpc_cs_char_set_compat_check ( 2242 client->codesets[0].c_set, 2243 server->codesets[0].c_set, 2244 status ); 2245 2246 if (*status != rpc_s_ok) 2247 { 2248 rpc_ns_mgmt_free_codesets(&server, &temp_status); 2249 rpc_ns_mgmt_free_codesets(&client, &temp_status); 2250 return; 2251 } 2252 2253 smir_true = cmir_true = model_found = 0; 2254 2255 for (i = 1; i <= server->count; i++) 2256 { 2257 if (model_found) 2258 break; 2259 2260 if (client->codesets[0].c_set 2261 == server->codesets[i].c_set) 2262 { 2263 smir_true = 1; 2264 model_found = 1; 2265 } 2266 2267 if (server->codesets[0].c_set 2268 == client->codesets[i].c_set) 2269 { 2270 cmir_true = 1; 2271 model_found = 1; 2272 } 2273 } 2274 2275 if (model_found) 2276 { 2277 tags_p = &bind_p->cs_eval.tagged_union.tags_key; 2278 2279 if (smir_true && cmir_true) 2280 { 2281 /* RMIR model works */ 2282 *p_stag = client->codesets[0].c_set; 2283 *p_drtag = server->codesets[0].c_set; 2284 2285 tags_p->stag = *p_stag; 2286 tags_p->drtag = *p_drtag; 2287 tags_p->stag_max_bytes = client->codesets[0].c_max_bytes; 2288 tags_p->client_tag = client->codesets[0].c_set; 2289 tags_p->client_max_bytes = client->codesets[0].c_max_bytes; 2290 tags_p->type_handle = NULL; 2291 } 2292 else if (smir_true) 2293 { 2294 /* SMIR model */ 2295 *p_stag = client->codesets[0].c_set; 2296 *p_drtag = client->codesets[0].c_set; 2297 2298 tags_p->stag = *p_stag; 2299 tags_p->drtag = *p_drtag; 2300 tags_p->stag_max_bytes = client->codesets[0].c_max_bytes; 2301 tags_p->client_tag = client->codesets[0].c_set; 2302 tags_p->client_max_bytes = client->codesets[0].c_max_bytes; 2303 tags_p->type_handle = NULL; 2304 } 2305 else 2306 { 2307 /* CMIR model */ 2308 *p_stag = server->codesets[0].c_set; 2309 *p_drtag = server->codesets[0].c_set; 2310 2311 tags_p->stag = *p_stag; 2312 tags_p->drtag = *p_drtag; 2313 tags_p->stag_max_bytes = server->codesets[0].c_max_bytes; 2314 tags_p->client_tag = client->codesets[0].c_set; 2315 tags_p->client_max_bytes = client->codesets[0].c_max_bytes; 2316 tags_p->type_handle = NULL; 2317 } 2318 *status = rpc_s_ok; 2319 } 2320 else 2321 { 2322 /* Try to find the intermediate code set */ 2323 tags_p->client_tag = client->codesets[0].c_set; 2324 tags_p->client_max_bytes = client->codesets[0].c_max_bytes; 2325 tags_p->type_handle = NULL; 2326 2327 for (i = 1; i <= client->count; i++) 2328 { 2329 if (model_found) 2330 break; 2331 2332 for (j = 1; j <= server->count; j++) 2333 { 2334 if (client->codesets[i].c_set 2335 == server->codesets[j].c_set) 2336 { 2337 *p_stag = client->codesets[i].c_set; 2338 *p_drtag = client->codesets[i].c_set; 2339 tags_p->stag = *p_stag; 2340 tags_p->drtag = *p_drtag; 2341 tags_p->stag_max_bytes = client->codesets[i].c_max_bytes; 2342 model_found = 1; 2343 break; 2344 } 2345 } 2346 } 2347 2348 if (!model_found) 2349 { 2350 /* We use UNIVERSAL code set */ 2351 *p_stag = UCS2_L2; 2352 *p_drtag = UCS2_L2; 2353 tags_p->stag = *p_stag; 2354 tags_p->drtag = *p_drtag; 2355 tags_p->stag_max_bytes = client->codesets[i].c_max_bytes; 2356 2357 rpc_rgy_get_max_bytes ( 2358 UCS2_L2, 2359 &tags_p->stag_max_bytes, 2360 status 2361 ); 2362 } 2363 } 2364 } 2365 2366 rpc_ns_mgmt_free_codesets(&server, &temp_status); 2367 rpc_ns_mgmt_free_codesets(&client, &temp_status); 2368 bind_p->extended_bind_flag = RPC_C_BH_EXTENDED_CODESETS; 2369 } 2370 } 2371 else /* server side */ 2372 { 2373 if (p_rtag != p_drtag) 2374 *p_rtag = *p_drtag; 2375 2376 *status = rpc_s_ok; 2377 } 2378 return; 2379} 2380