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** 80** NAME: 81** 82** COMTWR.C 83** 84** FACILITY: 85** 86** Remote procedure call (RPC) 87** 88** ABSTRACT: 89** 90** Set of routines supporting operations that create and manipulate the 91** canonical representation of a protocol tower. 92** 93** 94**/ 95 96#include <commonp.h> /* Private defs for Common component */ 97#include <com.h> /* Private COM defs for other RPC components */ 98#include <comp.h> /* Privates for COM Services component */ 99#include <comtwr.h> /* Private tower defs */ 100#include <comtwrref.h> /* Private tower ref defs for other RPC components */ 101 102 103/* 104**++ 105** ROUTINE NAME: rpc__tower_free 106** 107** SCOPE: PRIVATE - declared in comtwr.h 108** 109** DESCRIPTION: 110** 111** Releases memory used by a tower that was dynamically created. 112** Towers are dynamically created by calling the 113** rpc__tower_from_tower_ref routine. 114** 115** INPUTS: none 116** 117** INPUT/OUTPUTS: 118** 119** tower Canonical representation of a protocol tower. 120** Nulled on return. 121** 122** OUTPUTS: 123** 124** status Returns the status code from the free 125** operation. This status code indicates whether the 126** routine completed successfully and, if not, why. 127** Returns rpc_s_ok. 128** 129** IMPLICIT INPUTS: none 130** 131** IMPLICIT OUTPUTS: none 132** 133** FUNCTION VALUE: none 134** 135** SIDE EFFECTS: none 136** 137**-- 138*/ 139 140PRIVATE void rpc__tower_free 141( 142 twr_p_t *tower, 143 unsigned32 *status 144) 145{ 146 CODING_ERROR (status); 147 148 RPC_MEM_FREE (*tower, RPC_C_MEM_TOWER); 149 *tower = NULL; 150 151 *status = rpc_s_ok; 152 return; 153} 154 155 156/* 157**++ 158** ROUTINE NAME: rpc__tower_from_tower_ref 159** 160** SCOPE: PRIVATE - declared in comtwr.h 161** 162** DESCRIPTION: 163** 164** This routine creates the canonical representation of a protocol tower 165** from a runtime reference representation of a protocol tower. 166** 167** INPUTS: 168** 169** tower_ref Runtime reference representation of a protocol tower. 170** 171** INPUT/OUTPUTS: none 172** 173** OUTPUTS: 174** 175** tower Returns a pointer to the canonical representation 176** of a protocol tower. 177** 178** status Returns the status code from the 179** tower from tower_ref operation. This status code 180** indicates whether the routine completed 181** successfully and, if not, why. 182** Returns 183** rpc_s_ok 184** or status from a called routine. 185** 186** IMPLICIT INPUTS: none 187** 188** IMPLICIT OUTPUTS: none 189** 190** FUNCTION VALUE: 191** 192** void 193** 194** SIDE EFFECTS: none 195** 196**-- 197*/ 198 199PRIVATE void rpc__tower_from_tower_ref 200( 201 rpc_tower_ref_p_t tower_ref, 202 twr_p_t *tower, 203 unsigned32 *status 204) 205{ 206 byte_p_t tower_p; 207 unsigned16 twr_rep_16; 208 unsigned32 i, 209 floor_size, 210 octet_length; 211 212 /* 213 * Calculate the size of the tower octet string. 214 */ 215 for (i = 0, octet_length = 0; 216 i < tower_ref->count; i++) 217 { 218 octet_length += (tower_ref->floor[i]->prot_id_count + 219 RPC_C_TOWER_FLR_LHS_COUNT_SIZE + 220 tower_ref->floor[i]->address_count + 221 RPC_C_TOWER_FLR_RHS_COUNT_SIZE); 222 } 223 224 octet_length += RPC_C_TOWER_FLR_COUNT_SIZE; 225 226 /* 227 * Allocate the tower structure to hold the 228 * canonical representation of the tower. 229 */ 230 RPC_MEM_ALLOC ( 231 *tower, 232 twr_p_t, 233 sizeof (twr_t) + octet_length - 1, 234 RPC_C_MEM_TOWER, RPC_C_MEM_WAITOK ); 235 236 /* 237 * Initialize the tower length in the tower structure. 238 */ 239 (*tower)->tower_length = octet_length; 240 241 /* 242 * Form the tower octet string starting 243 * with the tower floor count size. 244 */ 245 tower_p = (*tower)->tower_octet_string; 246 247 /* 248 * Convert the tower count to little endian 249 * and copy it to the octet string. 250 */ 251 twr_rep_16 = tower_ref->count; 252 RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); 253 memcpy ((char *)tower_p, 254 (char *)&twr_rep_16, RPC_C_TOWER_FLR_COUNT_SIZE); 255 256 tower_p += RPC_C_TOWER_FLR_COUNT_SIZE; 257 258 /* 259 * And now copy each tower floor to the octet string. 260 */ 261 for (i=0; i < tower_ref->count; i++) 262 { 263 floor_size = 264 RPC_C_TOWER_FLR_LHS_COUNT_SIZE + 265 tower_ref->floor[i]->prot_id_count + 266 RPC_C_TOWER_FLR_RHS_COUNT_SIZE + 267 tower_ref->floor[i]->address_count; 268 269 memcpy ((char *)tower_p, (char *)tower_ref->floor[i]->octet_string, 270 floor_size); 271 272 tower_p += floor_size; 273 } 274 275 *status = rpc_s_ok; 276 return; 277} 278 279 280/* 281**++ 282** ROUTINE NAME: rpc__tower_to_tower_ref 283** 284** SCOPE: PRIVATE - declared in comtwr.h 285** 286** DESCRIPTION: 287** 288** Creates a runtime reference representation of a protocol tower 289** from a canonical representation of a protocol tower. 290** 291** INPUTS: 292** 293** tower Canonical representation of a protocol tower. 294** 295** INPUT/OUTPUTS: none 296** 297** OUTPUTS: 298** 299** tower_ref Returns a pointer to a reference representation 300** of a protocol tower. 301** status Returns the status code from the tower to tower ref 302** operation. This status code indicates whether the 303** routine completed successfully and, if not, why. 304** Returns 305** rpc_s_ok 306** or status from a called routine. 307** 308** IMPLICIT INPUTS: none 309** 310** IMPLICIT OUTPUTS: none 311** 312** FUNCTION VALUE: void 313** 314** SIDE EFFECTS: none 315** 316**-- 317*/ 318 319PRIVATE void rpc__tower_to_tower_ref 320( 321 twr_p_t tower, 322 rpc_tower_ref_p_t *tower_ref, 323 unsigned32 *status 324) 325{ 326 unsigned16 floor_count; 327 328 CODING_ERROR (status); 329 330 /* 331 * Get the tower floor count and correct for proper endian. 332 */ 333 memcpy ((char *) &floor_count, (char *) tower->tower_octet_string, 334 RPC_C_TOWER_FLR_COUNT_SIZE); 335 RPC_RESOLVE_ENDIAN_INT16 (floor_count); 336 337 /* 338 * Allocate and initialize the tower reference structure to be returned. 339 */ 340 rpc__tower_ref_alloc (tower->tower_octet_string, floor_count, 1, 341 tower_ref, status); 342 343 /* 344 * Return status from the tower ref allocate operation. 345 */ 346 return; 347} 348 349 350/* 351**++ 352** ROUTINE NAME: rpc_tower_to_binding 353** 354** SCOPE: PUBLIC - declared in rpc.idl 355** 356** DESCRIPTION: 357** 358** Creates a binding handle from a canonical representation of a 359** protocol tower. After the caller is finished with the binding, the 360** rpc_binding_free routine must be called to release the memory used 361** by the binding. 362** 363** Note, this is an SPI routine - available to outside the runtime, 364** but only to other DCE components. 365** 366** INPUTS: 367** 368** prot_tower A single protocol tower (DNA$Tower attribute value) 369** to convert to a binding handle. 370** 371** INPUT/OUTPUTS: none 372** 373** OUTPUTS: 374** 375** binding Returns a binding handle. 376** status Returns the status code from the tower-to-binding 377** operation. This status code indicates whether the 378** routine completed successfully and, if not, why. 379** Returns 380** rpc_s_ok 381** or status from a called routine. 382** 383** IMPLICIT INPUTS: none 384** 385** IMPLICIT OUTPUTS: none 386** 387** FUNCTION VALUE: void 388** 389** SIDE EFFECTS: none 390** 391**-- 392*/ 393 394PUBLIC void rpc_tower_to_binding 395( 396 byte_p_t prot_tower, 397 rpc_binding_handle_t *binding, 398 unsigned32 *status 399) 400{ 401 rpc_binding_rep_p_t binding_rep; 402 rpc_protocol_id_t prot_id; 403 rpc_addr_p_t rpc_addr; 404 405 CODING_ERROR (status); 406 RPC_VERIFY_INIT (); 407 408 /* 409 * Null binding in case of error before finishing. 410 */ 411 *binding = NULL; 412 413 /* 414 * Obtain an RPC address for the tower. 415 */ 416 rpc__naf_tower_flrs_to_addr (prot_tower, &rpc_addr, status); 417 if (*status != rpc_s_ok) 418 { 419 return; 420 } 421 422 prot_id = RPC_PROTSEQ_INQ_PROT_ID(rpc_addr->rpc_protseq_id); 423 424 /* 425 * Allocate and initialize a binding rep. 426 */ 427 binding_rep = rpc__binding_alloc 428 (false, &uuid_g_nil_uuid, prot_id, rpc_addr, status); 429 430 /* 431 * Return binding handle to user. 432 */ 433 *binding = (rpc_binding_handle_t) binding_rep; 434 435 /* 436 * Return status from rpc__binding_alloc 437 */ 438 return; 439 440} 441 442 443/* 444**++ 445** ROUTINE NAME: rpc_tower_vector_from_binding 446** 447** SCOPE: PUBLIC - declared in rpc.idl 448** 449** DESCRIPTION: 450** 451** Creates a vector of twr_t's from a binding handle. After the caller is 452** finished with the tower vector, the rpc_tower_vector_free routine must be 453** called to release the memory used by the vector. 454** 455** Note, this is an SPI routine - available to outside the runtime, 456** but only to other DCE components. 457** 458** INPUTS: 459** 460** if_spec Interface spec to combine with a binding 461** handle to form a tower vector. 462** 463** binding Binding handle to combine with an interface 464** spec to form a tower vector. 465** 466** INPUT/OUTPUTS: none 467** 468** OUTPUTS: 469** 470** tower_vector Returns an allocated tower vector. 471** 472** status Returns the status code from the 473** tower-vector-from-binding operation. 474** This status code indicates whether the 475** routine completed successfully and, if not, why. 476** Returns 477** rpc_s_ok 478** rpc_s_no_interfaces 479** or status from a called routine. 480** 481** IMPLICIT INPUTS: none 482** 483** IMPLICIT OUTPUTS: none 484** 485** FUNCTION VALUE: void 486** 487** SIDE EFFECTS: none 488** 489**-- 490*/ 491 492PUBLIC void rpc_tower_vector_from_binding 493( 494 rpc_if_handle_t if_spec, 495 rpc_binding_handle_t binding, 496 rpc_tower_vector_p_t *twr_vector, 497 unsigned32 *status 498) 499{ 500 rpc_tower_ref_vector_t *tower_ref_vector; 501 unsigned int i; 502 unsigned32 temp_status; 503 504 CODING_ERROR (status); 505 RPC_VERIFY_INIT (); 506 507 /* 508 * Null the twr_vector in case of error before finishing. 509 */ 510 *twr_vector = NULL; 511 512 if (if_spec == NULL) 513 { 514 *status = rpc_s_no_interfaces; 515 return; 516 } 517 518 /* 519 * Convert the binding to a vector of tower refs. 520 */ 521 522 rpc__tower_ref_vec_from_binding ((rpc_if_rep_p_t)if_spec, binding, 523 &tower_ref_vector, status); 524 525 if (*status != rpc_s_ok) 526 { 527 /* 528 * No need to goto CLEANUP; since a tower_ref_vector wasn't 529 * returned to us. 530 */ 531 return; 532 } 533 534 /* 535 * Allocate a rpc_tower_vector_t based on the number of returned 536 * tower refs. 537 */ 538 RPC_MEM_ALLOC ( 539 *twr_vector, 540 rpc_tower_vector_p_t, 541 sizeof (rpc_tower_vector_t) + (tower_ref_vector->count - 1) * 542 sizeof (twr_p_t), 543 RPC_C_MEM_TOWER_VECTOR, 544 RPC_C_MEM_WAITOK ); 545 546 (*twr_vector)->count = tower_ref_vector->count; 547 548 /* 549 * For each returned tower ref convert the tower ref to a twr_t and 550 * store the twr_t in the rpc_tower_vector_t. 551 */ 552 for (i = 0; i < tower_ref_vector->count; i++) 553 { 554 rpc__tower_from_tower_ref (tower_ref_vector->tower[i], 555 &(*twr_vector)->tower[i], status); 556 557 if (*status != rpc_s_ok) 558 { 559 RPC_MEM_FREE (*twr_vector, RPC_C_MEM_TOWER_VECTOR); 560 561 goto CLEANUP; 562 } 563 } 564 565CLEANUP: 566 /* 567 * Free the tower_ref_vector returned from 568 * rpc__tower_ref_vec_from_binding(). 569 */ 570 rpc__tower_ref_vec_free (&tower_ref_vector, &temp_status); 571 572 /* 573 * If we got this far successfully, return whatever the result from 574 * rpc__tower_ref_vec_free(). Otherwise, return the previous error 575 * in status. 576 */ 577 if (*status == rpc_s_ok) 578 { 579 *status = temp_status; 580 } 581 582 return; 583} 584 585/* 586**++ 587** ROUTINE NAME: rpc_tower_vector_free 588** 589** SCOPE: PRIVATE - declared in comtwrref.h 590** 591** DESCRIPTION: 592** 593** Releases memory associated with a tower vector, 594** including the towers as well as the vector. 595** 596** INPUTS: none 597** 598** INPUT/OUTPUTS: 599** 600** twr_vector The tower vector to free. Nulled on return. 601** 602** OUTPUTS: 603** 604** status Returns the status code from the tower free 605** operation. This status code is a value that 606** indicates whether the routine completed 607** successfully and, if not, why. 608** Returns 609** rpc_s_ok 610** or status from a called routine. 611** 612** IMPLICIT INPUTS: none 613** 614** IMPLICIT OUTPUTS: none 615** 616** FUNCTION VALUE: void 617** 618** SIDE EFFECTS: none 619** 620**-- 621*/ 622 623PRIVATE void rpc_tower_vector_free 624( 625 rpc_tower_vector_p_t *twr_vector, 626 unsigned32 *status 627) 628{ 629 unsigned32 i; 630 631 CODING_ERROR (status); 632 633 /* 634 * Free each tower reference in the vector. 635 */ 636 for (i=0; i < (*twr_vector)->count; i++) 637 { 638 rpc__tower_free (&((*twr_vector)->tower[i]), status); 639 if (*status != rpc_s_ok) 640 { 641 return; 642 } 643 } 644 645 /* 646 * Free the tower vector structure and set pointer to NULL. 647 */ 648 RPC_MEM_FREE (*twr_vector, RPC_C_MEM_TOWER_VECTOR); 649 650 *twr_vector = NULL; 651 652 *status = rpc_s_ok; 653 return; 654} 655