/* * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Inc. ("Apple") nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Portions of this software have been released under the following terms: * * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION * * To anyone who acknowledges that this file is provided "AS IS" * without any express or implied warranty: * permission to use, copy, modify, and distribute this file for any * purpose is hereby granted without fee, provided that the above * copyright notices and this notice appears in all source code copies, * and that none of the names of Open Software Foundation, Inc., Hewlett- * Packard Company or Digital Equipment Corporation be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Neither Open Software * Foundation, Inc., Hewlett-Packard Company nor Digital * Equipment Corporation makes any representations about the suitability * of this software for any purpose. * * Copyright (c) 2007, Novell, Inc. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Novell Inc. nor the names of its contributors * may be used to endorse or promote products derived from this * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @APPLE_LICENSE_HEADER_END@ */ /* ** ** ** NAME: ** ** COMTWR.C ** ** FACILITY: ** ** Remote procedure call (RPC) ** ** ABSTRACT: ** ** Set of routines supporting operations that create and manipulate the ** canonical representation of a protocol tower. ** ** **/ #include /* Private defs for Common component */ #include /* Private COM defs for other RPC components */ #include /* Privates for COM Services component */ #include /* Private tower defs */ #include /* Private tower ref defs for other RPC components */ /* **++ ** ROUTINE NAME: rpc__tower_free ** ** SCOPE: PRIVATE - declared in comtwr.h ** ** DESCRIPTION: ** ** Releases memory used by a tower that was dynamically created. ** Towers are dynamically created by calling the ** rpc__tower_from_tower_ref routine. ** ** INPUTS: none ** ** INPUT/OUTPUTS: ** ** tower Canonical representation of a protocol tower. ** Nulled on return. ** ** OUTPUTS: ** ** status Returns the status code from the free ** operation. This status code indicates whether the ** routine completed successfully and, if not, why. ** Returns rpc_s_ok. ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: none ** ** SIDE EFFECTS: none ** **-- */ PRIVATE void rpc__tower_free ( twr_p_t *tower, unsigned32 *status ) { CODING_ERROR (status); RPC_MEM_FREE (*tower, RPC_C_MEM_TOWER); *tower = NULL; *status = rpc_s_ok; return; } /* **++ ** ROUTINE NAME: rpc__tower_from_tower_ref ** ** SCOPE: PRIVATE - declared in comtwr.h ** ** DESCRIPTION: ** ** This routine creates the canonical representation of a protocol tower ** from a runtime reference representation of a protocol tower. ** ** INPUTS: ** ** tower_ref Runtime reference representation of a protocol tower. ** ** INPUT/OUTPUTS: none ** ** OUTPUTS: ** ** tower Returns a pointer to the canonical representation ** of a protocol tower. ** ** status Returns the status code from the ** tower from tower_ref operation. This status code ** indicates whether the routine completed ** successfully and, if not, why. ** Returns ** rpc_s_ok ** or status from a called routine. ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: ** ** void ** ** SIDE EFFECTS: none ** **-- */ PRIVATE void rpc__tower_from_tower_ref ( rpc_tower_ref_p_t tower_ref, twr_p_t *tower, unsigned32 *status ) { byte_p_t tower_p; unsigned16 twr_rep_16; unsigned32 i, floor_size, octet_length; /* * Calculate the size of the tower octet string. */ for (i = 0, octet_length = 0; i < tower_ref->count; i++) { octet_length += (tower_ref->floor[i]->prot_id_count + RPC_C_TOWER_FLR_LHS_COUNT_SIZE + tower_ref->floor[i]->address_count + RPC_C_TOWER_FLR_RHS_COUNT_SIZE); } octet_length += RPC_C_TOWER_FLR_COUNT_SIZE; /* * Allocate the tower structure to hold the * canonical representation of the tower. */ RPC_MEM_ALLOC ( *tower, twr_p_t, sizeof (twr_t) + octet_length - 1, RPC_C_MEM_TOWER, RPC_C_MEM_WAITOK ); /* * Initialize the tower length in the tower structure. */ (*tower)->tower_length = octet_length; /* * Form the tower octet string starting * with the tower floor count size. */ tower_p = (*tower)->tower_octet_string; /* * Convert the tower count to little endian * and copy it to the octet string. */ twr_rep_16 = tower_ref->count; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tower_p, (char *)&twr_rep_16, RPC_C_TOWER_FLR_COUNT_SIZE); tower_p += RPC_C_TOWER_FLR_COUNT_SIZE; /* * And now copy each tower floor to the octet string. */ for (i=0; i < tower_ref->count; i++) { floor_size = RPC_C_TOWER_FLR_LHS_COUNT_SIZE + tower_ref->floor[i]->prot_id_count + RPC_C_TOWER_FLR_RHS_COUNT_SIZE + tower_ref->floor[i]->address_count; memcpy ((char *)tower_p, (char *)tower_ref->floor[i]->octet_string, floor_size); tower_p += floor_size; } *status = rpc_s_ok; return; } /* **++ ** ROUTINE NAME: rpc__tower_to_tower_ref ** ** SCOPE: PRIVATE - declared in comtwr.h ** ** DESCRIPTION: ** ** Creates a runtime reference representation of a protocol tower ** from a canonical representation of a protocol tower. ** ** INPUTS: ** ** tower Canonical representation of a protocol tower. ** ** INPUT/OUTPUTS: none ** ** OUTPUTS: ** ** tower_ref Returns a pointer to a reference representation ** of a protocol tower. ** status Returns the status code from the tower to tower ref ** operation. This status code indicates whether the ** routine completed successfully and, if not, why. ** Returns ** rpc_s_ok ** or status from a called routine. ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- */ PRIVATE void rpc__tower_to_tower_ref ( twr_p_t tower, rpc_tower_ref_p_t *tower_ref, unsigned32 *status ) { unsigned16 floor_count; CODING_ERROR (status); /* * Get the tower floor count and correct for proper endian. */ memcpy ((char *) &floor_count, (char *) tower->tower_octet_string, RPC_C_TOWER_FLR_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (floor_count); /* * Allocate and initialize the tower reference structure to be returned. */ rpc__tower_ref_alloc (tower->tower_octet_string, floor_count, 1, tower_ref, status); /* * Return status from the tower ref allocate operation. */ return; } /* **++ ** ROUTINE NAME: rpc_tower_to_binding ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** Creates a binding handle from a canonical representation of a ** protocol tower. After the caller is finished with the binding, the ** rpc_binding_free routine must be called to release the memory used ** by the binding. ** ** Note, this is an SPI routine - available to outside the runtime, ** but only to other DCE components. ** ** INPUTS: ** ** prot_tower A single protocol tower (DNA$Tower attribute value) ** to convert to a binding handle. ** ** INPUT/OUTPUTS: none ** ** OUTPUTS: ** ** binding Returns a binding handle. ** status Returns the status code from the tower-to-binding ** operation. This status code indicates whether the ** routine completed successfully and, if not, why. ** Returns ** rpc_s_ok ** or status from a called routine. ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- */ PUBLIC void rpc_tower_to_binding ( byte_p_t prot_tower, rpc_binding_handle_t *binding, unsigned32 *status ) { rpc_binding_rep_p_t binding_rep; rpc_protocol_id_t prot_id; rpc_addr_p_t rpc_addr; CODING_ERROR (status); RPC_VERIFY_INIT (); /* * Null binding in case of error before finishing. */ *binding = NULL; /* * Obtain an RPC address for the tower. */ rpc__naf_tower_flrs_to_addr (prot_tower, &rpc_addr, status); if (*status != rpc_s_ok) { return; } prot_id = RPC_PROTSEQ_INQ_PROT_ID(rpc_addr->rpc_protseq_id); /* * Allocate and initialize a binding rep. */ binding_rep = rpc__binding_alloc (false, &uuid_g_nil_uuid, prot_id, rpc_addr, status); /* * Return binding handle to user. */ *binding = (rpc_binding_handle_t) binding_rep; /* * Return status from rpc__binding_alloc */ return; } /* **++ ** ROUTINE NAME: rpc_tower_vector_from_binding ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** Creates a vector of twr_t's from a binding handle. After the caller is ** finished with the tower vector, the rpc_tower_vector_free routine must be ** called to release the memory used by the vector. ** ** Note, this is an SPI routine - available to outside the runtime, ** but only to other DCE components. ** ** INPUTS: ** ** if_spec Interface spec to combine with a binding ** handle to form a tower vector. ** ** binding Binding handle to combine with an interface ** spec to form a tower vector. ** ** INPUT/OUTPUTS: none ** ** OUTPUTS: ** ** tower_vector Returns an allocated tower vector. ** ** status Returns the status code from the ** tower-vector-from-binding operation. ** This status code indicates whether the ** routine completed successfully and, if not, why. ** Returns ** rpc_s_ok ** rpc_s_no_interfaces ** or status from a called routine. ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- */ PUBLIC void rpc_tower_vector_from_binding ( rpc_if_handle_t if_spec, rpc_binding_handle_t binding, rpc_tower_vector_p_t *twr_vector, unsigned32 *status ) { rpc_tower_ref_vector_t *tower_ref_vector; unsigned int i; unsigned32 temp_status; CODING_ERROR (status); RPC_VERIFY_INIT (); /* * Null the twr_vector in case of error before finishing. */ *twr_vector = NULL; if (if_spec == NULL) { *status = rpc_s_no_interfaces; return; } /* * Convert the binding to a vector of tower refs. */ rpc__tower_ref_vec_from_binding ((rpc_if_rep_p_t)if_spec, binding, &tower_ref_vector, status); if (*status != rpc_s_ok) { /* * No need to goto CLEANUP; since a tower_ref_vector wasn't * returned to us. */ return; } /* * Allocate a rpc_tower_vector_t based on the number of returned * tower refs. */ RPC_MEM_ALLOC ( *twr_vector, rpc_tower_vector_p_t, sizeof (rpc_tower_vector_t) + (tower_ref_vector->count - 1) * sizeof (twr_p_t), RPC_C_MEM_TOWER_VECTOR, RPC_C_MEM_WAITOK ); (*twr_vector)->count = tower_ref_vector->count; /* * For each returned tower ref convert the tower ref to a twr_t and * store the twr_t in the rpc_tower_vector_t. */ for (i = 0; i < tower_ref_vector->count; i++) { rpc__tower_from_tower_ref (tower_ref_vector->tower[i], &(*twr_vector)->tower[i], status); if (*status != rpc_s_ok) { RPC_MEM_FREE (*twr_vector, RPC_C_MEM_TOWER_VECTOR); goto CLEANUP; } } CLEANUP: /* * Free the tower_ref_vector returned from * rpc__tower_ref_vec_from_binding(). */ rpc__tower_ref_vec_free (&tower_ref_vector, &temp_status); /* * If we got this far successfully, return whatever the result from * rpc__tower_ref_vec_free(). Otherwise, return the previous error * in status. */ if (*status == rpc_s_ok) { *status = temp_status; } return; } /* **++ ** ROUTINE NAME: rpc_tower_vector_free ** ** SCOPE: PRIVATE - declared in comtwrref.h ** ** DESCRIPTION: ** ** Releases memory associated with a tower vector, ** including the towers as well as the vector. ** ** INPUTS: none ** ** INPUT/OUTPUTS: ** ** twr_vector The tower vector to free. Nulled on return. ** ** OUTPUTS: ** ** status Returns the status code from the tower free ** operation. This status code is a value that ** indicates whether the routine completed ** successfully and, if not, why. ** Returns ** rpc_s_ok ** or status from a called routine. ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- */ PRIVATE void rpc_tower_vector_free ( rpc_tower_vector_p_t *twr_vector, unsigned32 *status ) { unsigned32 i; CODING_ERROR (status); /* * Free each tower reference in the vector. */ for (i=0; i < (*twr_vector)->count; i++) { rpc__tower_free (&((*twr_vector)->tower[i]), status); if (*status != rpc_s_ok) { return; } } /* * Free the tower vector structure and set pointer to NULL. */ RPC_MEM_FREE (*twr_vector, RPC_C_MEM_TOWER_VECTOR); *twr_vector = NULL; *status = rpc_s_ok; return; }