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** 79** pickling.c 80** 81** FACILITY: 82** 83** Interface Definition Language (IDL) Compiler 84** 85** ABSTRACT: 86** 87** Routines for IDL encoding services 88** 89*/ 90#if HAVE_CONFIG_H 91#include <config.h> 92#endif 93 94#include <assert.h> 95 96#include <dce/idlddefs.h> 97#include <ndrmi.h> 98#include <ndrui.h> 99#include <dce/rpcsts.h> 100#include <lsysdep.h> 101 102static rpc_syntax_id_t ndr_transfer_syntax_id = { 103 {0x8a885d04, 0x1ceb, 0x11c9, 0x9f, 0xe8, {0x8, 0x0, 0x2b, 0x10, 0x48, 1040x60}}, 105 2}; 106 107/******************************************************************************/ 108/* */ 109/* idl_es_add_state_to_handle - local routine */ 110/* Allocate an IDL_ms_t block, initialize it, and attach it to an encoding */ 111/* handle */ 112/* Also mark the state block's copy of the pickle header as invalid */ 113/* Returns error_status_ok or rpc_s_no_memory */ 114/* */ 115/******************************************************************************/ 116static error_status_t idl_es_add_state_to_handle 117( 118 IDL_es_state_t *p_es_state 119) 120{ 121 IDL_msp_t IDL_msp; 122 123 IDL_msp = (IDL_msp_t)malloc(sizeof(IDL_ms_t)); 124 if (IDL_msp == NULL) 125 return(rpc_s_no_memory); 126 /* Initialize state block, except stub must fill in type vector */ 127 rpc_ss_init_marsh_state(NULL, IDL_msp); 128 IDL_msp->IDL_pickling_handle = (rpc_void_p_t)p_es_state; 129 p_es_state->IDL_msp = IDL_msp; 130 p_es_state->IDL_pickle_header.IDL_op_num = IDL_INVALID_OP_NUM; 131 return(error_status_ok); 132} 133 134/******************************************************************************/ 135/* */ 136/* idl_es_encode_incremental - API routine */ 137/* Return an encoding handle for incremental encoding */ 138/* */ 139/******************************************************************************/ 140void idl_es_encode_incremental 141( 142 idl_void_p_t state, /* [in] user state */ 143 idl_es_allocate_fn_t alloc, /* [in] alloc routine */ 144 idl_es_write_fn_t writefn, /* [in] write routine */ 145 idl_es_handle_t *h, /* [out] encoding handle */ 146 error_status_t *st /* [out] status */ 147) 148{ 149 IDL_es_state_t *p_es_state; 150 151 p_es_state = (IDL_es_state_t *)malloc(sizeof(IDL_es_state_t)); 152 if (p_es_state == NULL) 153 { 154 *st = rpc_s_no_memory; 155 return; 156 } 157 158 p_es_state->IDL_version = IDL_ES_STATE_VERSION; 159 p_es_state->IDL_action = IDL_encoding_k; 160 p_es_state->IDL_style = IDL_incremental_k; 161 /* Set transfer syntax null to indicate "not yet determined" */ 162 uuid_create_nil(&(p_es_state->IDL_pickle_header.IDL_syntax_id.id), st); 163 p_es_state->IDL_pickle_header.IDL_syntax_id.version = 0; 164 p_es_state->IDL_state = state; 165 p_es_state->IDL_alloc = alloc; 166 p_es_state->IDL_write = writefn; 167 p_es_state->IDL_es_flags = 0; 168 169 *st = idl_es_add_state_to_handle(p_es_state); 170 if (*st == error_status_ok) 171 *h = (idl_es_handle_t)p_es_state; 172 else 173 free(p_es_state); 174} 175 176/******************************************************************************/ 177/* */ 178/* idl_es_encode_fixed_buffer - API routine */ 179/* Return an encoding handle for fixed buffer encoding */ 180/* */ 181/******************************************************************************/ 182void idl_es_encode_fixed_buffer 183( 184 idl_byte *ep, /* [out] buffer to */ 185 /* receive the encoding (must */ 186 /* be 8-byte aligned). */ 187 idl_ulong_int bsize, /* [in] size of buffer provided */ 188 idl_ulong_int *esize, /* [out] size of the resulting */ 189 /* encoding (set after */ 190 /* execution of the stub) */ 191 idl_es_handle_t *h, /* [out] encoding handle */ 192 error_status_t *st /* [out] status */ 193) 194{ 195 IDL_es_state_t *p_es_state; 196 197 p_es_state = (IDL_es_state_t *)malloc(sizeof(IDL_es_state_t)); 198 if (p_es_state == NULL) 199 { 200 *st = rpc_s_no_memory; 201 return; 202 } 203 204 p_es_state->IDL_version = IDL_ES_STATE_VERSION; 205 p_es_state->IDL_action = IDL_encoding_k; 206 p_es_state->IDL_style = IDL_fixed_k; 207 /* Set transfer syntax null to indicate "not yet determined" */ 208 uuid_create_nil(&(p_es_state->IDL_pickle_header.IDL_syntax_id.id), st); 209 p_es_state->IDL_pickle_header.IDL_syntax_id.version = 0; 210 if (((ep - (idl_byte *)0) & 7) != 0) 211 { 212 /* User buffer is not 8-byte aligned */ 213 free(p_es_state); 214 *st = rpc_s_ss_bad_buffer; 215 return; 216 } 217 p_es_state->IDL_buff_addr = ep; 218 if ((bsize & 7) != 0) 219 { 220 /* User buffer is not multiple of 8 bytes */ 221 free(p_es_state); 222 *st = rpc_s_ss_bad_buffer; 223 return; 224 } 225 p_es_state->IDL_bsize = bsize; 226 p_es_state->IDL_esize = esize; 227 p_es_state->IDL_es_flags = 0; 228 229 *st = idl_es_add_state_to_handle(p_es_state); 230 if (*st == error_status_ok) 231 { 232 *h = (idl_es_handle_t)p_es_state; 233 p_es_state->IDL_msp->IDL_mp = ep; 234 p_es_state->IDL_msp->IDL_buff_addr = ep; 235 p_es_state->IDL_msp->IDL_data_addr = ep; 236 p_es_state->IDL_msp->IDL_left_in_buff = bsize; 237 } 238 else 239 free(p_es_state); 240} 241 242/******************************************************************************/ 243/* */ 244/* idl_es_encode_dyn_buffer - API routine */ 245/* Return an encoding handle for dynamic buffer encoding */ 246/* */ 247/******************************************************************************/ 248void idl_es_encode_dyn_buffer 249( 250 idl_byte **ep, /* [out] pointer to receive the */ 251 /* dynamically allocated buffer */ 252 /* which contains the encoding */ 253 idl_ulong_int *esize, /* [out] size of the resulting */ 254 /* encoding (set after */ 255 /* execution of the stub) */ 256 idl_es_handle_t *h, /* [out] decoding handle */ 257 error_status_t *st /* [out] status */ 258) 259{ 260 IDL_es_state_t *p_es_state; 261 262 p_es_state = (IDL_es_state_t *)malloc(sizeof(IDL_es_state_t)); 263 if (p_es_state == NULL) 264 { 265 *st = rpc_s_no_memory; 266 return; 267 } 268 269 p_es_state->IDL_version = IDL_ES_STATE_VERSION; 270 p_es_state->IDL_action = IDL_encoding_k; 271 p_es_state->IDL_style = IDL_dynamic_k; 272 /* Set transfer syntax null to indicate "not yet determined" */ 273 uuid_create_nil(&(p_es_state->IDL_pickle_header.IDL_syntax_id.id), st); 274 p_es_state->IDL_pickle_header.IDL_syntax_id.version = 0; 275 p_es_state->IDL_p_buff_addr = ep; 276 *ep = NULL; /* Marker to indicate that no encoding call has yet been 277 made using this handle */ 278 p_es_state->IDL_esize = esize; 279 p_es_state->IDL_dyn_buff_chain_head = NULL; 280 p_es_state->IDL_dyn_buff_chain_tail = NULL; 281 p_es_state->IDL_es_flags = 0; 282 283 *st = idl_es_add_state_to_handle(p_es_state); 284 if (*st == error_status_ok) 285 *h = (idl_es_handle_t)p_es_state; 286 else 287 free(p_es_state); 288} 289 290/******************************************************************************/ 291/* */ 292/* idl_es_decode_incremental - API routine */ 293/* Return an encoding handle for incremental decoding */ 294/* */ 295/******************************************************************************/ 296void idl_es_decode_incremental 297( 298 idl_void_p_t state, /* [in] user state */ 299 idl_es_read_fn_t readfn, /* [in] routine to supply buffers */ 300 idl_es_handle_t *h, /* [out] decoding handle */ 301 error_status_t *st /* [out] status */ 302) 303{ 304 IDL_es_state_t *p_es_state; 305 IDL_msp_t IDL_msp; 306 307 p_es_state = (IDL_es_state_t *)malloc(sizeof(IDL_es_state_t)); 308 if (p_es_state == NULL) 309 { 310 *st = rpc_s_no_memory; 311 return; 312 } 313 314 p_es_state->IDL_version = IDL_ES_STATE_VERSION; 315 p_es_state->IDL_action = IDL_decoding_k; 316 p_es_state->IDL_style = IDL_incremental_k; 317 p_es_state->IDL_state = state; 318 p_es_state->IDL_read = readfn; 319 p_es_state->IDL_pickle_header_read = idl_false; 320 p_es_state->IDL_es_flags = 0; 321 322 *st = idl_es_add_state_to_handle(p_es_state); 323 if (*st == error_status_ok) 324 { 325 *h = (idl_es_handle_t)p_es_state; 326 IDL_msp = p_es_state->IDL_msp; 327 IDL_msp->IDL_left_in_buff = 0; 328 } 329 else 330 free(p_es_state); 331} 332 333/******************************************************************************/ 334/* */ 335/* idl_es_decode_buffer - API routine */ 336/* Return an encoding handle for fixed decoding */ 337/* */ 338/******************************************************************************/ 339void idl_es_decode_buffer 340( 341 idl_byte *ep, /* [in] pointer to buffer */ 342 /* containing the encoding */ 343 idl_ulong_int size, /* [in] size of buffer provided */ 344 idl_es_handle_t *h, /* [out] decoding handle */ 345 error_status_t *st /* [out] status */ 346) 347{ 348 IDL_es_state_t *p_es_state; 349 IDL_msp_t IDL_msp; 350 351 p_es_state = (IDL_es_state_t *)malloc(sizeof(IDL_es_state_t)); 352 if (p_es_state == NULL) 353 { 354 *st = rpc_s_no_memory; 355 return; 356 } 357 358 p_es_state->IDL_version = IDL_ES_STATE_VERSION; 359 p_es_state->IDL_action = IDL_decoding_k; 360 p_es_state->IDL_style = IDL_fixed_k; 361 p_es_state->IDL_bsize = size; 362 p_es_state->IDL_buff_addr = ep; 363 p_es_state->IDL_pickle_header_read = idl_false; 364 p_es_state->IDL_es_flags = 0; 365 366 *st = idl_es_add_state_to_handle(p_es_state); 367 if (*st == error_status_ok) 368 *h = (idl_es_handle_t)p_es_state; 369 else 370 { 371 free(p_es_state); 372 return; 373 } 374 375 /* Set up buffer management state */ 376 IDL_msp = p_es_state->IDL_msp; 377 if (((p_es_state->IDL_buff_addr - (idl_byte *)0) & 7) != 0) 378 { 379 /* User buffer is not 8-byte aligned. Copy data to an area 380 that is */ 381 p_es_state->IDL_align_buff_addr = (idl_byte *) 382 malloc(p_es_state->IDL_bsize + 7); 383 if (p_es_state->IDL_align_buff_addr == NULL) 384 { 385 free(p_es_state); 386 *st = rpc_s_no_memory; 387 return; 388 } 389 IDL_msp->IDL_data_addr = (idl_byte *) 390 (((p_es_state->IDL_align_buff_addr - (idl_byte *)0) + 7) & (~7)); 391 memcpy(IDL_msp->IDL_data_addr, p_es_state->IDL_buff_addr, 392 p_es_state->IDL_bsize); 393 } 394 else 395 { 396 p_es_state->IDL_align_buff_addr = NULL; 397 IDL_msp->IDL_data_addr = p_es_state->IDL_buff_addr; 398 } 399 IDL_msp->IDL_mp = IDL_msp->IDL_data_addr; 400 IDL_msp->IDL_left_in_buff = p_es_state->IDL_bsize; 401} 402 403/******************************************************************************/ 404/* */ 405/* idl_es_set_transfer_syntax - API routine */ 406/* Set a transfer syntax (user must call this before encoding using a stub */ 407/* which supports more than one transfer syntax) */ 408/* */ 409/******************************************************************************/ 410void idl_es_set_transfer_syntax 411( 412 idl_es_handle_t h, /* [in,out] User's encoding handle */ 413 idl_es_transfer_syntax_t es_transfer_syntax, 414 /* [in] requested transfer syntax */ 415 error_status_t *st 416) 417{ 418 IDL_es_state_t *p_es_state; 419 420 p_es_state = (IDL_es_state_t *)h; 421 switch (es_transfer_syntax) 422 { 423 case idl_es_transfer_syntax_ndr: 424 p_es_state->IDL_pickle_header.IDL_syntax_id 425 = ndr_transfer_syntax_id; 426 *st = error_status_ok; 427 break; 428 default: 429 *st = rpc_s_tsyntaxes_unsupported; 430 break; 431 } 432} 433 434/******************************************************************************/ 435/* */ 436/* idl_es_check_transfer_syntax - local routine */ 437/* Check the stub supports the transfer syntax and return the appropriate */ 438/* enumeration value */ 439/* */ 440/******************************************************************************/ 441static void idl_es_check_transfer_syntax 442( 443 rpc_if_rep_t *p_if_spec, /* [in] Pointer to stub's if_spec */ 444 IDL_es_state_t *p_es_state, /* [in] State block containing transfer syntax 445 to be checked */ 446 idl_es_transfer_syntax_t *p_es_transfer_syntax, 447 /* [out] Transfer syntax to use for encoding */ 448 IDL_msp_t IDL_msp 449) 450{ 451 unsigned32 i; 452 453 /* Check the stub supports the transfer syntax */ 454 for (i=0; i<p_if_spec->syntax_vector.count; i++) 455 { 456 if ( uuid_equal(&(p_es_state->IDL_pickle_header.IDL_syntax_id.id), 457 &(p_if_spec->syntax_vector.syntax_id[i].id), 458 (error_status_t *)&IDL_msp->IDL_status) 459 && (p_es_state->IDL_pickle_header.IDL_syntax_id.version 460 == p_if_spec->syntax_vector.syntax_id[i].version) ) 461 { 462 break; 463 } 464 } 465 if ( i >= p_if_spec->syntax_vector.count ) 466 { 467 /* No match found in list in stub's ifspec */ 468 IDL_msp->IDL_status = rpc_s_tsyntaxes_unsupported; 469 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 470 } 471 472 /* Return the enumeration value for the transfer syntax */ 473 *p_es_transfer_syntax = idl_es_transfer_syntax_ndr; 474} 475 476/******************************************************************************/ 477/* */ 478/* idl_es_encode_get_xfer_syntax - local routine */ 479/* Get the transfer syntax to be used for the encoding */ 480/* */ 481/******************************************************************************/ 482static void idl_es_encode_get_xfer_syntax 483( 484 idl_es_handle_t h, /* [in] User's encoding handle */ 485 rpc_if_handle_t ifp, /* [in] Pointer to stub's ifspec */ 486 idl_es_transfer_syntax_t *p_es_transfer_syntax, 487 /* [out] Transfer syntax to use for encoding */ 488 IDL_msp_t IDL_msp 489) 490{ 491 IDL_es_state_t *p_es_state; 492 rpc_if_rep_t *p_if_spec; 493 494 p_es_state = (IDL_es_state_t *)h; 495 p_if_spec = (rpc_if_rep_t *)ifp; 496 if ( uuid_is_nil(&(p_es_state->IDL_pickle_header.IDL_syntax_id.id), 497 (error_status_t *)&IDL_msp->IDL_status) ) 498 { 499 /* No transfer syntax specified in the handle, 500 so can the transfer syntax to use be determined from the stub? */ 501 if (p_if_spec->syntax_vector.count != 1) 502 { 503 /* Transfer syntax not adequately specified by stub */ 504 IDL_msp->IDL_status = rpc_s_tsyntaxes_unsupported; 505 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 506 } 507 else 508 { 509 /* Copy the transfer syntax into the encoding state block */ 510 p_es_state->IDL_pickle_header.IDL_syntax_id = 511 *(p_if_spec->syntax_vector.syntax_id); 512 } 513 } 514 515 /* Check the stub supports the transfer syntax the user chose */ 516 idl_es_check_transfer_syntax(p_if_spec, p_es_state, p_es_transfer_syntax, 517 IDL_msp); 518} 519 520/******************************************************************************/ 521/* */ 522/* idl_es_encode_new_dyn_buff - Called locally and from MIA/BER support */ 523/* Create new intermediate buffer list element */ 524/* Returns error_status_ok or rpc_s_no_memory */ 525/* Does not raise exceptions because it can be called from below DDIS */ 526/* */ 527/******************************************************************************/ 528error_status_t idl_es_encode_new_dyn_buff 529( 530 idl_ulong_int *p_buff_size, /* [out] Size of buffer returned */ 531 IDL_msp_t IDL_msp 532) 533{ 534 IDL_dyn_buff_link_t *p_new_link; 535 rpc_iovector_elt_t *p_new_iovec_elt; 536 IDL_es_state_t *p_es_state; 537 538 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 539 540 if ( (*(p_es_state->IDL_p_buff_addr) != NULL) 541 && (p_es_state->IDL_dyn_buff_chain_head == NULL) ) 542 { 543 /* A previous encoding operation was called using the current 544 encoding handle (signified by IDL_p_buff_addr not NULL) 545 and this is the first intermediate buffer needed by the 546 current operation (signified by IDL_dyn_buff_chain_head == NULL). 547 Make the output from the preceding operation(s) be the first element 548 of the list of intermediate buffers */ 549 p_new_link = (IDL_dyn_buff_link_t *)malloc 550 (sizeof(IDL_dyn_buff_link_t)); 551 if (p_new_link == NULL) 552 { 553 rpc_allocator_free(&IDL_msp->IDL_allocator, 554 *(p_es_state->IDL_p_buff_addr)); 555 return(rpc_s_no_memory); 556 } 557 p_new_link->IDL_p_iovec_elt = NULL; 558 p_new_link->IDL_next = NULL; 559 p_es_state->IDL_dyn_buff_chain_head = p_new_link; 560 p_es_state->IDL_dyn_buff_chain_tail = p_new_link; 561 /* Create an rpc_iovector_elt to describe the buffer */ 562 p_new_iovec_elt = (rpc_iovector_elt_t *)malloc 563 (sizeof(rpc_iovector_elt_t)); 564 if (p_new_iovec_elt == NULL) 565 { 566 rpc_allocator_free(&IDL_msp->IDL_allocator, 567 *(p_es_state->IDL_p_buff_addr)); 568 return(rpc_s_no_memory); 569 } 570 p_new_link->IDL_p_iovec_elt = p_new_iovec_elt; 571 p_new_iovec_elt->buff_addr = *(p_es_state->IDL_p_buff_addr); 572 p_new_iovec_elt->data_addr = *(p_es_state->IDL_p_buff_addr); 573 p_new_iovec_elt->data_len = *(p_es_state->IDL_esize); 574 } 575 576 p_new_link = (IDL_dyn_buff_link_t *)malloc 577 (sizeof(IDL_dyn_buff_link_t)); 578 if (p_new_link == NULL) 579 return(rpc_s_no_memory); 580 p_new_link->IDL_p_iovec_elt = NULL; 581 p_new_link->IDL_next = NULL; 582 /* Connect it to the state block */ 583 if (p_es_state->IDL_dyn_buff_chain_head == NULL) 584 p_es_state->IDL_dyn_buff_chain_head = p_new_link; 585 else 586 p_es_state->IDL_dyn_buff_chain_tail->IDL_next = p_new_link; 587 p_es_state->IDL_dyn_buff_chain_tail = p_new_link; 588 /* Create an rpc_iovector_elt to describe the buffer */ 589 p_new_iovec_elt = (rpc_iovector_elt_t *)malloc 590 (sizeof(rpc_iovector_elt_t)); 591 if (p_new_iovec_elt == NULL) 592 return(rpc_s_no_memory); 593 p_new_iovec_elt->buff_addr = NULL; 594 /* Attach the rpc_iovector_elt to the chain */ 595 p_new_link->IDL_p_iovec_elt = p_new_iovec_elt; 596 /* Create the buffer */ 597 IDL_msp->IDL_buff_addr = (idl_byte *) 598 rpc_allocator_allocate(&IDL_msp->IDL_allocator, IDL_BUFF_SIZE); 599 if (IDL_msp->IDL_buff_addr == NULL) 600 return(rpc_s_no_memory); 601 memset(IDL_msp->IDL_buff_addr, 0, IDL_BUFF_SIZE); 602 /* Attach the buffer to the rpc_iovector_elt */ 603 p_new_iovec_elt->buff_addr = IDL_msp->IDL_buff_addr; 604 *p_buff_size = IDL_BUFF_SIZE; 605 return(error_status_ok); 606} 607 608/******************************************************************************/ 609/* */ 610/* idl_es_encode_init_buffer - called from NDR marshalling interpreter */ 611/* Action to be taken by rpc_ss_marsh_init_buffer when used for encoding */ 612/* */ 613/******************************************************************************/ 614void idl_es_encode_init_buffer 615( 616 idl_ulong_int *p_buff_size, /* [out] Size of buffer returned */ 617 IDL_msp_t IDL_msp 618) 619{ 620 IDL_es_state_t *p_es_state; 621 622 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 623 switch (p_es_state->IDL_style) 624 { 625 case IDL_incremental_k: 626 *p_buff_size = IDL_BUFF_SIZE; 627 (*(p_es_state->IDL_alloc))(p_es_state->IDL_state, 628 &IDL_msp->IDL_buff_addr, p_buff_size); 629 if (((IDL_msp->IDL_buff_addr - (idl_byte *)0) & 7) != 0) 630 { 631 /* User buffer is not 8-byte aligned */ 632 IDL_msp->IDL_status = rpc_s_ss_bad_buffer; 633 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 634 } 635 if (((*p_buff_size & 7) != 0) || (*p_buff_size < 8)) 636 { 637 /* User buffer is not multiple of 8 bytes */ 638 IDL_msp->IDL_status = rpc_s_ss_bad_buffer; 639 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 640 } 641 break; 642 case IDL_fixed_k: 643 /* Ran out of buffer space with data still to be marshalled */ 644 DCETHREAD_RAISE(rpc_x_no_memory); 645 break; 646 case IDL_dynamic_k: 647 /* Create new intermediate buffer list element */ 648 if (idl_es_encode_new_dyn_buff(p_buff_size, IDL_msp) 649 != error_status_ok) 650 DCETHREAD_RAISE(rpc_x_no_memory); 651 break; 652 default: 653#ifdef DEBUG_INTERP 654 printf("idl_es_encode_init_buffer - unknown encoding style\n"); 655 exit(0); 656#endif 657 DCETHREAD_RAISE(rpc_x_coding_error); 658 } 659} 660 661/******************************************************************************/ 662/* */ 663/* idl_es_encode_attach_buff - called from NDR marshalling interpreter */ 664/* Action to be taken by rpc_ss_attach_buff_to_iovec when used for encoding */ 665/* */ 666/******************************************************************************/ 667void idl_es_encode_attach_buff 668( 669 IDL_msp_t IDL_msp 670) 671{ 672 IDL_es_state_t *p_es_state; 673 rpc_iovector_elt_t *p_iovec_elt; 674 675 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 676 switch (p_es_state->IDL_style) 677 { 678 case IDL_incremental_k: 679 (*(p_es_state->IDL_write))(p_es_state->IDL_state, 680 IDL_msp->IDL_buff_addr, 681 IDL_msp->IDL_mp - IDL_msp->IDL_data_addr); 682 break; 683 case IDL_fixed_k: 684 /* Can only happen at end of operation - do nothing */ 685 break; 686 case IDL_dynamic_k: 687 p_iovec_elt = p_es_state->IDL_dyn_buff_chain_tail->IDL_p_iovec_elt; 688 p_iovec_elt->data_addr = (byte_p_t)IDL_msp->IDL_data_addr; 689 p_iovec_elt->data_len = IDL_msp->IDL_mp - IDL_msp->IDL_data_addr; 690 break; 691 default: 692#ifdef DEBUG_INTERP 693 printf("idl_es_encode_attach_buff - unknown encoding style\n"); 694 exit(0); 695#endif 696 DCETHREAD_RAISE(rpc_x_coding_error); 697 } 698} 699 700/******************************************************************************/ 701/* */ 702/* idl_es_put_encoding_uuid - local routine */ 703/* Write a UUID in the header for a pickle */ 704/* */ 705/******************************************************************************/ 706static void idl_es_put_encoding_uuid 707( 708 idl_uuid_t *p_uuid, /* [in] Address of UUID */ 709 IDL_msp_t IDL_msp 710) 711{ 712 int i; 713 714 IDL_MARSH_ULONG(&p_uuid->time_low); 715 IDL_MARSH_USHORT(&p_uuid->time_mid); 716 IDL_MARSH_USHORT(&p_uuid->time_hi_and_version); 717 IDL_MARSH_USMALL(&p_uuid->clock_seq_hi_and_reserved); 718 IDL_MARSH_USMALL(&p_uuid->clock_seq_low); 719 for (i=0; i<6; i++) 720 { 721 IDL_MARSH_BYTE(&p_uuid->node[i]); 722 } 723} 724 725/******************************************************************************/ 726/* */ 727/* idl_es_put_encoding_header - local routine */ 728/* Write the header for this pickle */ 729/* */ 730/******************************************************************************/ 731static void idl_es_put_encoding_header 732( 733 rpc_if_handle_t ifp, /* [in] Pointer to stub's ifspec */ 734 idl_ulong_int op_num, /* [in] operation number */ 735 idl_es_transfer_syntax_t es_transfer_syntax, 736 /* [in] Transfer syntax user data will be encoded in */ 737 IDL_msp_t IDL_msp 738) 739{ 740 idl_usmall_int version = IDL_ES_HEADER_VERSION; 741 idl_usmall_int fill = 0; 742 IDL_es_state_t *p_es_state; 743 rpc_if_rep_t *p_if_spec; 744 int i; 745 idl_ushort_int vers_field; 746 747 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 748 p_if_spec = (rpc_if_rep_t *)ifp; 749 750 IDL_MARSH_USMALL(&version); 751 IDL_MARSH_USMALL(&ndr_g_local_drep.int_rep); 752 IDL_MARSH_USMALL(&fill); 753 IDL_MARSH_USMALL(&fill); 754 idl_es_put_encoding_uuid(&p_es_state->IDL_pickle_header.IDL_syntax_id.id, 755 IDL_msp); 756 IDL_MARSH_ULONG(&p_es_state->IDL_pickle_header.IDL_syntax_id.version); 757 idl_es_put_encoding_uuid(&p_if_spec->id, IDL_msp); 758 vers_field = p_if_spec->vers / 65536; /* Major version */ 759 IDL_MARSH_USHORT(&vers_field); 760 vers_field = p_if_spec->vers % 65536; /* Minor version */ 761 IDL_MARSH_USHORT(&vers_field); 762 IDL_MARSH_ULONG(&op_num); 763 if (es_transfer_syntax == idl_es_transfer_syntax_ndr) 764 { 765 IDL_MARSH_USMALL(&ndr_g_local_drep.int_rep); 766 IDL_MARSH_USMALL(&ndr_g_local_drep.char_rep); 767 IDL_MARSH_USMALL(&ndr_g_local_drep.float_rep); 768 IDL_MARSH_BYTE(&ndr_g_local_drep.reserved); 769 /* Four filler bytes to make the user data start at (0 mod 8) */ 770 for (i=0; i<4; i++) 771 { 772 IDL_MARSH_USMALL(&fill); 773 } 774 } 775 776 /* Store interface ID and operation number in state block */ 777 p_es_state->IDL_pickle_header.IDL_if_id.uuid = p_if_spec->id; 778 p_es_state->IDL_pickle_header.IDL_if_id.vers_major 779 = p_if_spec->vers / 65536; 780 p_es_state->IDL_pickle_header.IDL_if_id.vers_minor 781 = p_if_spec->vers % 65536; 782 p_es_state->IDL_pickle_header.IDL_op_num = op_num; 783} 784 785/******************************************************************************/ 786/* */ 787/* idl_es_get_encoding_uuid - local routine */ 788/* Read a UUID in the header for a pickle */ 789/* */ 790/******************************************************************************/ 791static void idl_es_get_encoding_uuid 792( 793 idl_uuid_t *p_uuid, /* [in] Address of UUID */ 794 IDL_msp_t IDL_msp 795) 796{ 797 int i; 798 799 IDL_UNMAR_ULONG(&p_uuid->time_low); 800 IDL_UNMAR_USHORT(&p_uuid->time_mid); 801 IDL_UNMAR_USHORT(&p_uuid->time_hi_and_version); 802 IDL_UNMAR_USMALL(&p_uuid->clock_seq_hi_and_reserved); 803 IDL_UNMAR_USMALL(&p_uuid->clock_seq_low); 804 for (i=0; i<6; i++) 805 { 806 IDL_UNMAR_BYTE(&p_uuid->node[i]); 807 } 808} 809 810/******************************************************************************/ 811/* */ 812/* idl_es_get_encoding_header - local routine */ 813/* Read pickle header into local storage */ 814/* */ 815/******************************************************************************/ 816static void idl_es_get_encoding_header 817( 818 idl_es_pvt_header_t *p_pickle_header, /* [out] local copy of pickle 819 header */ 820 IDL_msp_t IDL_msp 821) 822{ 823 IDL_es_state_t *p_es_state = NULL; 824 825 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 826 827 IDL_UNMAR_USMALL(&p_pickle_header->IDL_version); 828 if (p_pickle_header->IDL_version != IDL_ES_HEADER_VERSION) 829 { 830 IDL_msp->IDL_status = rpc_s_ss_wrong_es_version; 831 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 832 } 833 IDL_UNMAR_USMALL(&p_pickle_header->IDL_int_drep); 834 /* This drep is needed to control decoding the rest of header */ 835 IDL_msp->IDL_drep.int_rep = p_pickle_header->IDL_int_drep; 836 /* Called rtn will do an alignment operation, discarding the filler bytes */ 837 idl_es_get_encoding_uuid(&p_pickle_header->IDL_syntax_id.id, IDL_msp); 838 IDL_UNMAR_ULONG(&p_pickle_header->IDL_syntax_id.version); 839 idl_es_get_encoding_uuid(&p_pickle_header->IDL_if_id.uuid, IDL_msp); 840 IDL_UNMAR_USHORT(&p_pickle_header->IDL_if_id.vers_major); 841 IDL_UNMAR_USHORT(&p_pickle_header->IDL_if_id.vers_minor); 842 IDL_UNMAR_ULONG(&p_pickle_header->IDL_op_num); 843 844 /* If the pickle uses NDR encoding, get its drep's */ 845 if (uuid_equal(&p_pickle_header->IDL_syntax_id.id, 846 &ndr_transfer_syntax_id.id, 847 (error_status_t *)&IDL_msp->IDL_status)) 848 { 849 IDL_UNMAR_USMALL(&IDL_msp->IDL_drep.int_rep); 850 IDL_UNMAR_USMALL(&IDL_msp->IDL_drep.char_rep); 851 IDL_UNMAR_USMALL(&IDL_msp->IDL_drep.float_rep); 852 /* And align to 8 bytes */ 853 IDL_UNMAR_ALIGN_MP(IDL_msp, 8); 854 } 855 assert(p_es_state != NULL); 856 p_es_state->IDL_pickle_header_read = idl_true; 857} 858 859/* 860 * Support for Microsoft Encoding Services (MES). 861 */ 862static void idl_mes_put_encoding_header 863( 864 IDL_msp_t IDL_msp 865) 866{ 867 idl_es_type_pvt_header_t common_header; 868 int i; 869 idl_usmall_int hdr_length_low, hdr_length_high; 870 idl_byte length_pad = 0; 871 872 common_header.IDL_version = IDL_ES_HEADER_VERSION; 873 common_header.IDL_endianness = (ndr_g_local_drep.int_rep << 4); 874 common_header.IDL_common_header_length = IDL_ES_TYPE_COMMON_HEADER_LEN; 875 memset(common_header.IDL_fill, 0xcc, 4); 876 877 IDL_MARSH_USMALL(&common_header.IDL_version); 878 IDL_MARSH_USMALL(&common_header.IDL_endianness); 879 880 hdr_length_low = (common_header.IDL_common_header_length >> 0) & 0xff; 881 hdr_length_high = (common_header.IDL_common_header_length >> 8) & 0xff; 882 883 IDL_MARSH_USMALL(&hdr_length_low); 884 IDL_MARSH_USMALL(&hdr_length_high); 885 886 for (i = 0; i < 4; i++) 887 { 888 IDL_MARSH_BYTE(&common_header.IDL_fill[i]); 889 } 890 891 for (i = 0; i < 8; i++) 892 { 893 IDL_MARSH_BYTE(&length_pad); 894 } 895} 896 897static void idl_mes_get_encoding_header 898( 899 idl_es_pvt_header_t *p_pickle_header, 900 IDL_msp_t IDL_msp 901) 902{ 903 idl_es_type_pvt_header_t common_header; 904 IDL_es_state_t *p_es_state; 905 int i; 906 idl_uhyper_int length; 907 idl_usmall_int hdr_length_low, hdr_length_high; 908 unsigned32 status; 909 910 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 911 912 IDL_UNMAR_USMALL(&common_header.IDL_version); 913 if (common_header.IDL_version != IDL_ES_HEADER_VERSION) 914 { 915 IDL_msp->IDL_status = rpc_s_ss_wrong_es_version; 916 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 917 } 918 p_pickle_header->IDL_version = common_header.IDL_version; 919 920 IDL_UNMAR_USMALL(&common_header.IDL_endianness); 921 922 IDL_msp->IDL_drep.int_rep = (common_header.IDL_endianness >> 4) & 0xF; 923 924 IDL_UNMAR_USMALL(&hdr_length_low); 925 IDL_UNMAR_USMALL(&hdr_length_high); 926 927 common_header.IDL_common_header_length = (hdr_length_low << 0) | 928 (hdr_length_high << 8); 929 930 if (common_header.IDL_common_header_length != IDL_ES_TYPE_COMMON_HEADER_LEN) 931 { 932 IDL_msp->IDL_status = rpc_s_ss_wrong_es_version; 933 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 934 } 935 936 for (i = 0; i < common_header.IDL_common_header_length - 4; i++) 937 { 938 IDL_UNMAR_BYTE(&common_header.IDL_fill[i]); 939 } 940 941 IDL_UNMAR_HYPER(&length); 942 943 p_pickle_header->IDL_syntax_id = ndr_transfer_syntax_id; 944 uuid_create_nil(&p_pickle_header->IDL_if_id.uuid, &status); 945 if (status != rpc_s_ok) 946 { 947 IDL_msp->IDL_status = status; 948 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 949 } 950 p_pickle_header->IDL_if_id.vers_major = 0; 951 p_pickle_header->IDL_if_id.vers_minor = 0; 952 p_pickle_header->IDL_op_num = 0; 953 954 IDL_msp->IDL_drep.char_rep = ndr_c_char_ascii; 955 IDL_msp->IDL_drep.float_rep = ndr_c_float_ieee; 956 957 p_es_state->IDL_pickle_header_read = idl_true; 958} 959 960static void idl_mes_forge_encoding_header 961( 962 idl_es_pvt_header_t *p_pickle_header, 963 IDL_msp_t IDL_msp 964) 965{ 966 IDL_es_state_t *p_es_state; 967 unsigned32 status; 968 969 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 970 971 IDL_msp->IDL_drep.int_rep = ndr_c_int_little_endian; 972 973 p_pickle_header->IDL_syntax_id = ndr_transfer_syntax_id; 974 uuid_create_nil(&p_pickle_header->IDL_if_id.uuid, &status); 975 if (status != rpc_s_ok) 976 { 977 IDL_msp->IDL_status = status; 978 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 979 } 980 p_pickle_header->IDL_if_id.vers_major = 0; 981 p_pickle_header->IDL_if_id.vers_minor = 0; 982 p_pickle_header->IDL_op_num = 0; 983 984 IDL_msp->IDL_drep.int_rep = ndr_c_int_little_endian; 985 IDL_msp->IDL_drep.char_rep = ndr_c_char_ascii; 986 IDL_msp->IDL_drep.float_rep = ndr_c_float_ieee; 987 988 p_es_state->IDL_pickle_header_read = idl_true; 989} 990 991/******************************************************************************/ 992/* */ 993/* idl_es_before_interp_call - SPI routine */ 994/* Set up for interpreter call to encode/decode user data */ 995/* */ 996/******************************************************************************/ 997void idl_es_before_interp_call 998( 999 idl_es_handle_t h, /* [in] User's encoding handle */ 1000 rpc_if_handle_t ifp, /* [in] Pointer to stub's ifspec */ 1001 idl_byte IDL_type_vec[], /* [in] Stub's type vector */ 1002 idl_ulong_int op_num, /* [in] operation number */ 1003 IDL_es_action_type_k_t stub_action, /* [in] Is this operation labelled 1004 [encode], [decode] */ 1005 idl_es_transfer_syntax_t *p_es_transfer_syntax, 1006 /* [out] Transfer syntax to use for encoding */ 1007 IDL_msp_t IDL_msp 1008) 1009{ 1010 IDL_es_state_t * volatile p_es_state; 1011 rpc_if_rep_t *p_if_spec; 1012 1013 //DO_NOT_CLOBBER(p_es_state); 1014 p_es_state = NULL; 1015 1016 /* If we get any abnormal condition we need to cope with the situation 1017 where this is a dynamic encoding and the operation is not the first 1018 that used the handle. In this case we need to release the encoding 1019 resulting from the preceding operations */ 1020 DCETHREAD_TRY 1021 /* Complete initialization of state block */ 1022 IDL_msp->IDL_type_vec = IDL_type_vec; 1023 rpc_ss_type_vec_vers_check( IDL_msp ); 1024 1025 p_es_state = (IDL_es_state_t *)h; 1026 /* Was operation specified to support action? */ 1027 if (stub_action != IDL_both_k) 1028 { 1029 if (stub_action != p_es_state->IDL_action) 1030 { 1031 IDL_msp->IDL_status = rpc_s_ss_bad_es_action; 1032 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 1033 } 1034 } 1035 1036 if (p_es_state->IDL_action == IDL_encoding_k) 1037 { 1038 idl_es_encode_get_xfer_syntax(h, ifp, p_es_transfer_syntax, IDL_msp); 1039 if (p_es_state->IDL_style == IDL_dynamic_k) 1040 { 1041 /* Need user allocator for intermediate and final buffers */ 1042 rpc_ss_mts_client_estab_alloc(IDL_msp); 1043 } 1044 if ((p_es_state->IDL_es_flags & IDL_ES_NO_HEADER) == 0) 1045 { 1046 if (p_es_state->IDL_es_flags & IDL_ES_MIDL_COMPAT) 1047 idl_mes_put_encoding_header(IDL_msp); 1048 else 1049 idl_es_put_encoding_header(ifp, op_num, *p_es_transfer_syntax, IDL_msp); 1050 } 1051 } 1052 else /* decoding */ 1053 { 1054 if ( ! p_es_state->IDL_pickle_header_read ) 1055 { 1056 if (p_es_state->IDL_es_flags & IDL_ES_NO_HEADER) 1057 idl_mes_forge_encoding_header(&p_es_state->IDL_pickle_header, IDL_msp); 1058 else if (p_es_state->IDL_es_flags & IDL_ES_MIDL_COMPAT) 1059 idl_mes_get_encoding_header(&p_es_state->IDL_pickle_header, IDL_msp); 1060 else 1061 idl_es_get_encoding_header(&p_es_state->IDL_pickle_header, IDL_msp); 1062 } 1063 p_if_spec = (rpc_if_rep_t *)ifp; 1064 1065 /* 1066 * Don't check interface uuid's or version number if the user 1067 * doesn't want to. 1068 */ 1069 if ( ! (p_es_state->IDL_es_flags & ( IDL_ES_NO_ENCODING_CHECK 1070 | IDL_ES_MIDL_COMPAT 1071 | IDL_ES_NO_HEADER 1072 ) ) ) 1073 { 1074 if ( ! uuid_equal(&p_es_state->IDL_pickle_header.IDL_if_id.uuid, 1075 &p_if_spec->id, 1076 (error_status_t *)&IDL_msp->IDL_status) ) 1077 { 1078 /* Wrong interface */ 1079 IDL_msp->IDL_status = rpc_s_unknown_if; 1080 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 1081 } 1082 if (p_if_spec->vers != (unsigned32) 1083 (p_es_state->IDL_pickle_header.IDL_if_id.vers_major * 65536 1084 + p_es_state->IDL_pickle_header.IDL_if_id.vers_minor)) 1085 { 1086 /* Wrong version */ 1087 IDL_msp->IDL_status = rpc_s_unknown_if; 1088 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 1089 } 1090 } 1091 1092 /* Check the stub supports the transfer syntax of the pickle */ 1093 idl_es_check_transfer_syntax(p_if_spec, p_es_state, 1094 p_es_transfer_syntax, IDL_msp); 1095 /* Now at a point where we won't test for "pickle header read" again 1096 for this operation. Reset it in case user has another operation in 1097 the pickle */ 1098 p_es_state->IDL_pickle_header_read = idl_false; 1099 } 1100 DCETHREAD_CATCH_ALL(exc) 1101 assert(p_es_state != NULL); 1102 if ( (p_es_state->IDL_action == IDL_encoding_k) 1103 && (p_es_state->IDL_style == IDL_dynamic_k) 1104 && (*(p_es_state->IDL_p_buff_addr) != NULL) ) 1105 { 1106 rpc_allocator_free(&IDL_msp->IDL_allocator, 1107 *(p_es_state->IDL_p_buff_addr)); 1108 } 1109 DCETHREAD_RERAISE; 1110 DCETHREAD_ENDTRY 1111} 1112 1113/******************************************************************************/ 1114/* */ 1115/* idl_es_encode_dyn_size - local routine */ 1116/* Get the total size of a dynamic encoding */ 1117/* */ 1118/******************************************************************************/ 1119static void idl_es_encode_dyn_size 1120( 1121 IDL_dyn_buff_link_t *p_list_elt, /* [in] pointer to list of 1122 intermediate buffers */ 1123 idl_ulong_int *p_dyn_size /* [out] size of encoding */ 1124) 1125{ 1126 idl_ulong_int dyn_size = 0; 1127 1128 for ( ; p_list_elt != NULL; p_list_elt = p_list_elt->IDL_next) 1129 { 1130 dyn_size += p_list_elt->IDL_p_iovec_elt->data_len; 1131 } 1132 *p_dyn_size = dyn_size; 1133} 1134 1135/******************************************************************************/ 1136/* */ 1137/* idl_es_encode_dyn_copy_rel - local routine */ 1138/* Copy the intermediate buffers for a dynamic encoding to the buffer to be */ 1139/* delivered to the user, and release the intermediate buffer chain */ 1140/* */ 1141/******************************************************************************/ 1142static void idl_es_encode_dyn_copy_rel 1143( 1144 IDL_dyn_buff_link_t *p_list_elt, /* [in] pointer to list of 1145 intermediate buffers */ 1146 idl_byte *dyn_buff, /* [out] location to copy intermediate buffer to */ 1147 IDL_msp_t IDL_msp 1148) 1149{ 1150 rpc_iovector_elt_t *p_iovec_elt; 1151 idl_ulong_int inter_data_len; /* Length of data in intermediate buffer */ 1152 IDL_dyn_buff_link_t *p_old_list_elt; 1153 1154 while (p_list_elt != NULL) 1155 { 1156 p_iovec_elt = p_list_elt->IDL_p_iovec_elt; 1157 /* Copy data */ 1158 inter_data_len = p_iovec_elt->data_len; 1159 memcpy(dyn_buff, p_iovec_elt->data_addr, inter_data_len); 1160 dyn_buff += inter_data_len; 1161 /* Release head of chain */ 1162 rpc_allocator_free(&IDL_msp->IDL_allocator, p_iovec_elt->buff_addr); 1163 free(p_iovec_elt); 1164 p_old_list_elt = p_list_elt; 1165 p_list_elt = p_list_elt->IDL_next; 1166 free(p_old_list_elt); 1167 } 1168} 1169 1170/******************************************************************************/ 1171/* */ 1172/* idl_es_after_interp_call - SPI routine */ 1173/* Tidy up after normal return from interpreter call to encode/decode user */ 1174/* data */ 1175/* */ 1176/******************************************************************************/ 1177void idl_es_after_interp_call 1178( 1179 IDL_msp_t IDL_msp 1180) 1181{ 1182 IDL_es_state_t *p_es_state; 1183 rpc_iovector_elt_t *p_iovec_elt; 1184 idl_ulong_int dyn_size; /* Size of dynamic encoding */ 1185 idl_byte *dyn_buff; /* Dynamic buffer delivered to user */ 1186 1187 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 1188 1189 if (p_es_state->IDL_action == IDL_encoding_k) 1190 { 1191 switch (p_es_state->IDL_style) 1192 { 1193 case IDL_incremental_k: 1194 /* Last part of pickle already handed to user */ 1195 /* There may be another operation using the same handle 1196 - reset state */ 1197 if (IDL_msp->IDL_mem_handle.memory) 1198 { 1199 rpc_ss_mem_free(&IDL_msp->IDL_mem_handle); 1200 } 1201 rpc_ss_init_marsh_state(NULL, IDL_msp); 1202 IDL_msp->IDL_pickling_handle = (rpc_void_p_t)p_es_state; 1203 break; 1204 case IDL_fixed_k: 1205 /* Set size of pickle for user */ 1206 *(p_es_state->IDL_esize) = IDL_msp->IDL_mp 1207 - IDL_msp->IDL_data_addr; 1208 break; 1209 case IDL_dynamic_k: 1210 if ( (p_es_state->IDL_dyn_buff_chain_head->IDL_next == NULL) 1211 && (IDL_msp->IDL_data_addr == IDL_msp->IDL_buff_addr) ) 1212 { 1213 /* Intermediate buffer can be handed off to user */ 1214 p_iovec_elt = 1215 p_es_state->IDL_dyn_buff_chain_head->IDL_p_iovec_elt; 1216 *(p_es_state->IDL_p_buff_addr) = (idl_byte *) 1217 (p_iovec_elt->buff_addr); 1218 *(p_es_state->IDL_esize) = p_iovec_elt->data_len; 1219 /* Release chain machinery */ 1220 free(p_iovec_elt); 1221 free(p_es_state->IDL_dyn_buff_chain_head); 1222 } 1223 else 1224 { 1225 idl_es_encode_dyn_size(p_es_state->IDL_dyn_buff_chain_head, 1226 &dyn_size); 1227 *(p_es_state->IDL_esize) = dyn_size; 1228 dyn_buff = (idl_byte *) 1229 rpc_allocator_allocate( 1230 &IDL_msp->IDL_allocator, dyn_size); 1231 if (dyn_buff == NULL) 1232 DCETHREAD_RAISE(rpc_x_no_memory); 1233 memset(dyn_buff, 0, dyn_size); 1234 idl_es_encode_dyn_copy_rel( 1235 p_es_state->IDL_dyn_buff_chain_head, 1236 dyn_buff, IDL_msp); 1237 *(p_es_state->IDL_p_buff_addr) = dyn_buff; 1238 } 1239 p_es_state->IDL_dyn_buff_chain_head = NULL; 1240 /* There may be another operation using the same handle 1241 - reset state */ 1242 if (IDL_msp->IDL_mem_handle.memory) 1243 { 1244 rpc_ss_mem_free(&IDL_msp->IDL_mem_handle); 1245 } 1246 rpc_ss_init_marsh_state(NULL, IDL_msp); 1247 IDL_msp->IDL_pickling_handle = (rpc_void_p_t)p_es_state; 1248 break; 1249 default: 1250#ifdef DEBUG_INTERP 1251 printf( 1252 "idl_es_after_normal_interp_call - unknown encoding style\n"); 1253 exit(0); 1254#endif 1255 DCETHREAD_RAISE(rpc_x_coding_error); 1256 } 1257 1258 if (p_es_state->IDL_es_flags & IDL_ES_MIDL_COMPAT) 1259 { 1260 idl_byte *mp; 1261 idl_ulong_int length; /* length without header */ 1262 1263 length = *(p_es_state->IDL_esize) - IDL_ES_TYPE_HEADER_LEN; 1264 1265 if (p_es_state->IDL_style == IDL_fixed_k) 1266 mp = p_es_state->IDL_buff_addr; 1267 else if (p_es_state->IDL_style == IDL_dynamic_k) 1268 mp = *(p_es_state->IDL_p_buff_addr); 1269 else 1270 mp = NULL; 1271 1272 if (mp != NULL) 1273 { 1274 mp += IDL_ES_TYPE_COMMON_HEADER_LEN; 1275 1276 mp[0] = (length >> 0) & 0xff; 1277 mp[1] = (length >> 8) & 0xff; 1278 mp[2] = (length >> 16) & 0xff; 1279 mp[3] = (length >> 24) & 0xff; 1280 1281 memset(&mp[4], 0, 4); 1282 } 1283 } 1284 } 1285} 1286 1287/******************************************************************************/ 1288/* */ 1289/* idl_es_clean_up - SPI routine */ 1290/* Tidy up after un/pickling action */ 1291/* */ 1292/******************************************************************************/ 1293void idl_es_clean_up 1294( 1295 IDL_msp_t IDL_msp 1296) 1297{ 1298 IDL_es_state_t *p_es_state; 1299 IDL_dyn_buff_link_t *p_list_elt; 1300 IDL_dyn_buff_link_t *p_old_list_elt; 1301 rpc_iovector_elt_t *p_iovec_elt; 1302 1303 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 1304 1305 /* Tidy up if abnormal end during incremental encoding */ 1306 if (p_es_state->IDL_action == IDL_encoding_k) 1307 { 1308 if (p_es_state->IDL_style == IDL_dynamic_k) 1309 { 1310 p_list_elt = p_es_state->IDL_dyn_buff_chain_head; 1311 /* Release chain of intermediate buffers */ 1312 while (p_list_elt != NULL) 1313 { 1314 p_iovec_elt = p_list_elt->IDL_p_iovec_elt; 1315 if (p_iovec_elt != NULL) 1316 { 1317 if (p_iovec_elt->buff_addr != NULL) 1318 { 1319 rpc_allocator_free(&IDL_msp->IDL_allocator, 1320 p_iovec_elt->buff_addr); 1321 } 1322 free(p_iovec_elt); 1323 } 1324 p_old_list_elt = p_list_elt; 1325 p_list_elt = p_list_elt->IDL_next; 1326 free(p_old_list_elt); 1327 } 1328 p_es_state->IDL_dyn_buff_chain_head = NULL; 1329 } 1330 } 1331 /* Release memory allocated by interpreter */ 1332 if (IDL_msp->IDL_mem_handle.memory) 1333 { 1334 rpc_ss_mem_free(&IDL_msp->IDL_mem_handle); 1335 } 1336} 1337 1338/******************************************************************************/ 1339/* */ 1340/* idl_es_decode_check_buffer - called from NDR unmarshalling interpreter */ 1341/* Called when interpreter has exhausted current buffer */ 1342/* */ 1343/******************************************************************************/ 1344void idl_es_decode_check_buffer 1345( 1346 IDL_msp_t IDL_msp 1347) 1348{ 1349 IDL_es_state_t *p_es_state; 1350 1351 p_es_state = (IDL_es_state_t *)(IDL_msp->IDL_pickling_handle); 1352 if (p_es_state->IDL_style == IDL_incremental_k) 1353 { 1354 (*(p_es_state->IDL_read))(p_es_state->IDL_state, 1355 &IDL_msp->IDL_data_addr, 1356 &IDL_msp->IDL_left_in_buff); 1357 if (((IDL_msp->IDL_data_addr - (idl_byte *)0) & 7) != 0) 1358 { 1359 /* User buffer is not 8-byte aligned */ 1360 IDL_msp->IDL_status = rpc_s_ss_bad_buffer; 1361 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 1362 } 1363 IDL_msp->IDL_mp = IDL_msp->IDL_data_addr; 1364 } 1365 else /* Exhausted fixed buffer */ 1366 { 1367 IDL_msp->IDL_status = rpc_s_ss_bad_buffer; 1368 DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error); 1369 } 1370} 1371 1372/******************************************************************************/ 1373/* */ 1374/* idl_es_inq_encoding_id - API routine */ 1375/* Give interface ID and operation number to user */ 1376/* */ 1377/******************************************************************************/ 1378void idl_es_inq_encoding_id 1379( 1380 idl_es_handle_t h, /* [in] decoding handle */ 1381 rpc_if_id_t * volatile if_id, /* [out] RPC interface */ 1382 /* identifier (including */ 1383 /* version information) */ 1384 idl_ulong_int *op, /* [out] operation number */ 1385 error_status_t *st /* [out] status */ 1386) 1387{ 1388 IDL_es_state_t *p_es_state; 1389 1390 *st = error_status_ok; 1391 p_es_state = (IDL_es_state_t *)h; 1392 if ( (p_es_state->IDL_action == IDL_decoding_k) 1393 && ( ! p_es_state->IDL_pickle_header_read ) ) 1394 { 1395 /* User wants operation number before decoding pickle body */ 1396 DCETHREAD_TRY 1397 idl_es_get_encoding_header(&p_es_state->IDL_pickle_header, 1398 p_es_state->IDL_msp); 1399 DCETHREAD_CATCH(rpc_x_ss_pipe_comm_error) 1400 *st = p_es_state->IDL_msp->IDL_status; 1401 DCETHREAD_ENDTRY 1402 if (*st != error_status_ok) 1403 return; 1404 } 1405 else if (p_es_state->IDL_pickle_header.IDL_op_num == IDL_INVALID_OP_NUM) 1406 { 1407 /* Encoding, and no operation has yet been invoked */ 1408 *st = rpc_s_ss_bad_es_action; 1409 return; 1410 } 1411 *if_id = p_es_state->IDL_pickle_header.IDL_if_id; 1412 *op = p_es_state->IDL_pickle_header.IDL_op_num; 1413} 1414 1415/******************************************************************************/ 1416/* */ 1417/* idl_es_handle_free - API routine */ 1418/* Frees a idl_es_handle_t and its associated resources */ 1419/* */ 1420/******************************************************************************/ 1421void idl_es_handle_free 1422( 1423 idl_es_handle_t *h, /* [in,out] handle to free */ 1424 error_status_t *st /* [out] status */ 1425) 1426{ 1427 IDL_es_state_t *p_es_state; 1428 1429 p_es_state = (IDL_es_state_t *)(*h); 1430 free(p_es_state->IDL_msp); 1431 if ((p_es_state->IDL_action == IDL_decoding_k) 1432 && (p_es_state->IDL_style == IDL_fixed_k) 1433 && (p_es_state->IDL_align_buff_addr != NULL)) 1434 { 1435 free(p_es_state->IDL_align_buff_addr); 1436 } 1437 free(p_es_state); 1438 *h = NULL; 1439 *st = error_status_ok; 1440} 1441 1442/******************************************************************************/ 1443/* */ 1444/* idl_es_set_attrs - API routine */ 1445/* Set attribute flags in a idl_es_handle_t */ 1446/* */ 1447/******************************************************************************/ 1448void idl_es_set_attrs( 1449 idl_es_handle_t h, 1450 unsigned32 flags, 1451 error_status_t *st) 1452{ 1453 IDL_es_state_t *p_es_state = (IDL_es_state_t *)h; 1454 1455 p_es_state->IDL_es_flags = flags; 1456 *st = error_status_ok; 1457 return; 1458} 1459 1460/******************************************************************************/ 1461/* */ 1462/* idl_es_inq_attrs - API routine */ 1463/* Get the flags from a idl_es_handle_t */ 1464/* */ 1465/******************************************************************************/ 1466void idl_es_inq_attrs( 1467 idl_es_handle_t h, 1468 unsigned32 *flags, 1469 error_status_t *st) 1470{ 1471 IDL_es_state_t *p_es_state = (IDL_es_state_t *)h; 1472 1473 *flags = p_es_state->IDL_es_flags; 1474 *st = error_status_ok; 1475 return; 1476} 1477