/* * 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 ** ** comif.c ** ** FACILITY: ** ** Remote Procedure Call (RPC) ** ** ABSTRACT: ** ** Interface Service for the Common Communications Service. Contains ** routines to register an interface, unregister an interface, perform lookups ** of interface specifications within the Interface Registry Table, which is ** contained within this module. ** ** */ #include /* Common internals for RPC runtime system */ #include /* Externals for Common Services component */ #include /* Internals for Common Services component */ #include /* * the size of the interface registry hash table * - pick a prime number to avoid collisions */ #define RPC_C_IF_REGISTRY_SIZE 31 /* * The Interface Registry Table, where interface specifications * are registered, and upon which the routines contained within * this module perform their actions. Protected by "if_mutex". */ INTERNAL rpc_list_t if_registry[RPC_C_IF_REGISTRY_SIZE] = { {0,0} }; INTERNAL rpc_mutex_t if_mutex; /* * an if registry list entry */ typedef struct { rpc_list_t link; rpc_if_rep_p_t if_spec; rpc_mgr_epv_t default_mepv; unsigned copied_mepv: 1; /* 1 = mepv copied at registration time */ unsigned internal: 1; /* 1 = internal if; don't wildcard unregstr */ rpc_list_t type_info_list; unsigned32 flags; unsigned32 max_calls; unsigned32 max_rpc_size; rpc_if_callback_fn_t if_callback; } rpc_if_rgy_entry_t, *rpc_if_rgy_entry_p_t; /* * an if type/info list entry */ typedef struct { rpc_list_t link; idl_uuid_t type; /* type of object to which entry applies */ rpc_mgr_epv_t mepv; /* pointer to manager procedures */ unsigned copied_mepv: 1; /* 1 = mepv copied at registration time */ } rpc_if_type_info_t, *rpc_if_type_info_p_t; INTERNAL void unregister_if_entry ( rpc_if_rgy_entry_p_t /*if_entry*/, uuid_p_t /*mgr_type_uuid*/, unsigned32 * /*status*/ ); /* **++ ** ** ROUTINE NAME: rpc__if_init ** ** SCOPE: PRIVATE - declared in com.h ** ** DESCRIPTION: ** ** Initializes this module. ** ** INPUTS: none ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** status The result of the operation. ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__if_init ( unsigned32 * status ) { RPC_MUTEX_INIT (if_mutex); *status = rpc_s_ok; } /* **++ ** ** ROUTINE NAME: rpc__if_fork_handler ** ** SCOPE: PRIVATE - declared in com.h ** ** DESCRIPTION: ** ** Initializes this module. ** ** INPUTS: stage The stage of the fork we are ** currently handling. ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: none ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__if_fork_handler ( rpc_fork_stage_id_t stage ) { unsigned32 i; switch ((int)stage) { case RPC_C_PREFORK: break; case RPC_C_POSTFORK_PARENT: break; case RPC_C_POSTFORK_CHILD: /* * Empty the Interface Registry Table */ for (i = 0; i < RPC_C_IF_REGISTRY_SIZE; i++) { if_registry[i].next = NULL; if_registry[i].last = NULL; } break; } } /* **++ ** ** ROUTINE NAME: rpc_server_register_if ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** See description of "rpc__server_register_if_int". ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** mgr_type_uuid The interface type (if any) ** ** mgr_epv The manager epv for this interface ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_type_already_registered ** rpc_s_no_memory ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PUBLIC void rpc_server_register_if ( rpc_if_handle_t ifspec_h, uuid_p_t mgr_type_uuid, rpc_mgr_epv_t mgr_epv, unsigned32 *status ) { CODING_ERROR (status); RPC_VERIFY_INIT (); rpc__server_register_if_int (ifspec_h, mgr_type_uuid, mgr_epv, 0, rpc_c_listen_max_calls_default, -1, NULL, false, status); } /* **++ ** ** ROUTINE NAME: rpc__server_register_if_int ** ** SCOPE: PRIVATE - declared in com.h ** ** DESCRIPTION: ** ** Perform a hash lookup through the Interface Registry Table to try to ** locate the interface spec requested. If the search fails, add the ** interface entry to the appropriate list. Then proceed to insert the type ** uuid specified into the linked list for the requested interface. If the ** requested interface was located by the lookup, simply insert the type ** uuid. ** ** If a NULL manager entry point vector is specified, use the one in the ** ifspec. ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** mgr_type_uuid The interface type (if any) ** ** mgr_epv The manager epv for this interface ** ** flags Registration flags ** ** max_calls Maximum calls ** ** max_rpc_size Maximum RPC size (-1 for no maximum) ** ** if_callback Security callback ** ** is_internal T => manager should not be unregisterable by wildcarding ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_type_already_registered ** rpc_s_no_memory ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__server_register_if_int ( rpc_if_handle_t ifspec_h, uuid_p_t mgr_type_uuid, rpc_mgr_epv_t mgr_epv, unsigned32 flags, unsigned32 max_calls, unsigned32 max_rpc_size, rpc_if_callback_fn_t if_callback, boolean32 is_internal, unsigned32 *status ) { rpc_if_rep_p_t if_rep = (rpc_if_rep_p_t) ifspec_h; rpc_mgr_epv_t mepv; rpc_if_rgy_entry_p_t if_entry; unsigned32 index; unsigned32 ctr; boolean copied_mepv = false; boolean if_entry_alloced = false; boolean if_entry_added = false; CODING_ERROR (status); RPC_IF_VALIDATE(if_rep, status); if (*status != rpc_s_ok) { return; } /* * check to see if a NULL mgr_epv was passed * - if so, use the default one in the ifspec * - if it's non-NULL, make a copy of it */ if (mgr_epv == (rpc_mgr_epv_t) NULL) { mepv = if_rep->manager_epv; if (mepv == NULL) { *status = rpc_s_no_mepv; return; } } else { RPC_MEM_ALLOC ( mepv, rpc_mgr_epv_t, sizeof (rpc_mgr_epv_t *) + (sizeof (rpc_mgr_proc_t) * (if_rep->opcnt - 1)), RPC_C_MEM_MGR_EPV, RPC_C_MEM_WAITOK); if (mepv == NULL) { *status = rpc_s_no_memory; return; } /* * fill the manager epv entries into the copy */ for (ctr = 0; ctr < if_rep->opcnt; ctr++) { mepv[ctr] = mgr_epv[ctr]; } copied_mepv = true; } /* * compute a hash value using the interface uuid - check the status * from uuid_hash to make sure the uuid has a valid format */ index = (uuid_hash (&(if_rep->id), status)) % RPC_C_IF_REGISTRY_SIZE; if (*status != uuid_s_ok) { if (copied_mepv) { RPC_MEM_FREE (mepv, RPC_C_MEM_MGR_EPV); } return; } /* * take out a lock to protect access to the if registry */ RPC_MUTEX_LOCK (if_mutex); /* * see if the specified interface already exists in the registry */ RPC_LIST_FIRST (if_registry[index], if_entry, rpc_if_rgy_entry_p_t); while (if_entry != NULL) { /* * see if the if uuid and version match */ if ((UUID_EQ (if_entry->if_spec->id, if_rep->id, status)) && if_entry->if_spec->vers == if_rep->vers) { break; } RPC_LIST_NEXT (if_entry, if_entry, rpc_if_rgy_entry_p_t); } /* * if no entry was found, create one and add it to the list */ if (if_entry == NULL) { RPC_MEM_ALLOC ( if_entry, rpc_if_rgy_entry_p_t, sizeof (rpc_if_rgy_entry_t), RPC_C_MEM_IF_RGY_ENTRY, RPC_C_MEM_WAITOK); if (if_entry == NULL) { *status = rpc_s_no_memory; goto ERROR_AND_LOCKED; } if_entry_alloced = true; /* * initialize the entry */ if_entry->if_spec = if_rep; if_entry->default_mepv = NULL; if_entry->internal = is_internal; RPC_LIST_INIT (if_entry->type_info_list); if_entry->flags = flags; if_entry->max_calls = max_calls; if_entry->max_rpc_size = max_rpc_size; if_entry->if_callback = if_callback; /* * put it on the list for this hash index */ RPC_LIST_ADD_TAIL (if_registry[index], if_entry, rpc_if_rgy_entry_p_t); if_entry_added = true; } /* * see if a manager type was specified (and is non-nil) */ if (mgr_type_uuid != NULL && !(uuid_is_nil (mgr_type_uuid, status))) { rpc_if_type_info_p_t type_info = NULL; /* * see if the specified mgr type already exists for this entry */ RPC_LIST_FIRST (if_entry->type_info_list, type_info, rpc_if_type_info_p_t); while (type_info != NULL) { /* * see if the type uuid matches the one specified */ if (UUID_EQ (type_info->type, *mgr_type_uuid, status)) { *status = rpc_s_type_already_registered; goto ERROR_AND_LOCKED; } RPC_LIST_NEXT (type_info, type_info, rpc_if_type_info_p_t); } /* * no entry was found, create one and add it to the list */ assert (type_info == NULL); /* * malloc a type uuid/manager epv list element */ RPC_MEM_ALLOC ( type_info, rpc_if_type_info_p_t, sizeof (rpc_if_type_info_t), RPC_C_MEM_IF_TYPE_INFO, RPC_C_MEM_WAITOK); if (type_info == NULL) { *status = rpc_s_no_memory; goto ERROR_AND_LOCKED; } /* * fill in the supplied type info */ type_info->type = *mgr_type_uuid; type_info->mepv = mepv; type_info->copied_mepv = copied_mepv; /* * add the type info entry to the list for this interface */ RPC_LIST_ADD_TAIL (if_entry->type_info_list, type_info, rpc_if_type_info_p_t); } else { /* * set the default manager epv */ if (if_entry->default_mepv != NULL) { *status = rpc_s_type_already_registered; goto ERROR_AND_LOCKED; } if_entry->default_mepv = mepv; if_entry->copied_mepv = copied_mepv; } /* * free the global lock and return */ RPC_MUTEX_UNLOCK (if_mutex); *status = rpc_s_ok; return; ERROR_AND_LOCKED: /* * perform necessary cleanup, free the global lock and return * (the return status already set). */ if (if_entry_alloced) { if (if_entry_added) { RPC_LIST_REMOVE (if_registry[index], if_entry); } RPC_MEM_FREE (if_entry, RPC_C_MEM_IF_RGY_ENTRY); } if (copied_mepv) { RPC_MEM_FREE (mepv, RPC_C_MEM_MGR_EPV); } RPC_MUTEX_UNLOCK (if_mutex); return; } /* **++ ** ** ROUTINE NAME: rpc_server_unregister_if_int ** ** SCOPE: PRIVATE - declared in com.h ** ** DESCRIPTION: ** ** Perform a hash lookup on the Interface Registry Table to locate the ** specified interface spec. If the search fails, return ** 'rpc_s_unknown_if'. If a registered interface is located with the ** UUID and version specified in the if_spec, it is deleted from the ** Interface Registry Table along with the linked list of Type UUIDs. ** ** Also returns the pointer to the ifspec in the entry that was ** unregistered. This pointer turns out to be needed by the compatibility ** library. ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** mgr_type_uuid The type uuid of the manager epv to unregister. ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** rtn_ifspec_h Pointer to the ifspec that was in the entry that was ** unregistered. ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_unknown_if ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__server_unregister_if_int ( rpc_if_handle_t ifspec_h, uuid_p_t mgr_type_uuid, rpc_if_handle_t *rtn_ifspec_h, unsigned32 *status ) { rpc_if_rep_p_t if_rep = (rpc_if_rep_p_t) ifspec_h; unsigned32 index; rpc_if_rgy_entry_p_t if_entry, next_if_entry; boolean found_mgr_type; CODING_ERROR (status); *rtn_ifspec_h = NULL; /* * take out a lock to protect access to the if registry */ RPC_MUTEX_LOCK (if_mutex); /* * see what kind of unregister is wanted */ if (if_rep == NULL) { /* * go through the whole registry hash table */ for (index = 0, found_mgr_type = false; index < RPC_C_IF_REGISTRY_SIZE; index++) { /* * walk the list of entries for each hash value */ RPC_LIST_FIRST (if_registry[index], if_entry, rpc_if_rgy_entry_p_t); while (if_entry != NULL) { /* * do whatever unregister is required for this entry */ if (! if_entry->internal) { unregister_if_entry (if_entry, mgr_type_uuid, status); if (*status != rpc_s_ok) { if (*status != rpc_s_unknown_mgr_type) { RPC_MUTEX_UNLOCK (if_mutex); return; } } else { found_mgr_type = true; } } RPC_LIST_NEXT (if_entry, next_if_entry, rpc_if_rgy_entry_p_t); /* * See if there are any mgr types left for this interface * entry. If not, remove this entry from the list for this * hash value, and free the entry. */ if (RPC_LIST_EMPTY (if_entry->type_info_list) && if_entry->default_mepv == NULL) { RPC_LIST_REMOVE (if_registry[index], if_entry); RPC_MEM_FREE (if_entry, RPC_C_MEM_IF_RGY_ENTRY); } if_entry = next_if_entry; } } if (!found_mgr_type) { RPC_MUTEX_UNLOCK (if_mutex); *status = rpc_s_unknown_mgr_type; return; } } else { /* * compute a hash value using the interface uuid - check the status * from uuid_hash to make sure the uuid has a valid format */ index = uuid_hash (&(if_rep->id), status) % RPC_C_IF_REGISTRY_SIZE; if (*status != uuid_s_ok) { RPC_MUTEX_UNLOCK (if_mutex); return; } /* * walk the list of entries for this hash value */ RPC_LIST_FIRST (if_registry[index], if_entry, rpc_if_rgy_entry_p_t); while (if_entry != NULL) { if (! if_entry->internal) { /* * see if the if uuid and version match */ if ((UUID_EQ (if_entry->if_spec->id, if_rep->id, status)) && if_entry->if_spec->vers == if_rep->vers) { /* * snag the ifspec now, before the if entry (maybe) gets * freed. */ *rtn_ifspec_h = (rpc_if_handle_t) if_entry->if_spec; /* * do whatever unregister is required for this entry */ unregister_if_entry (if_entry, mgr_type_uuid, status); if (*status != rpc_s_ok) { RPC_MUTEX_UNLOCK (if_mutex); return; } /* * See if there are any mgr types left for this * interface entry. If not, remove this entry from * the list for this hash value, and free the entry. */ if (RPC_LIST_EMPTY (if_entry->type_info_list) && if_entry->default_mepv == NULL) { RPC_LIST_REMOVE (if_registry[index], if_entry); RPC_MEM_FREE (if_entry, RPC_C_MEM_IF_RGY_ENTRY); } /* * finished searching */ break; } } RPC_LIST_NEXT (if_entry, if_entry, rpc_if_rgy_entry_p_t); } if (*rtn_ifspec_h == NULL) { RPC_MUTEX_UNLOCK (if_mutex); *status = rpc_s_unknown_if; return; } } RPC_MUTEX_UNLOCK (if_mutex); *status = rpc_s_ok; return; } /* **++ ** ** ROUTINE NAME: rpc_server_unregister_if ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** See description of "rpc__server_unregister_int". ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** mgr_type_uuid The type uuid of the manager epv to unregister. ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_unknown_if ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PUBLIC void rpc_server_unregister_if ( rpc_if_handle_t ifspec_h, uuid_p_t mgr_type_uuid, unsigned32 *status ) { rpc_if_handle_t rtn_ifspec_h; CODING_ERROR (status); RPC_VERIFY_INIT (); rpc__server_unregister_if_int (ifspec_h, mgr_type_uuid, &rtn_ifspec_h, status); } /* ** This routine is called by rpc_server_unregister_if() to process a single ** interface entry in the if registry. **/ INTERNAL void unregister_if_entry ( rpc_if_rgy_entry_p_t if_entry, uuid_p_t mgr_type_uuid, unsigned32 *status ) { rpc_if_type_info_p_t type_info; rpc_if_type_info_p_t current_type_info; /* * see if this is a wildcard operation */ if (mgr_type_uuid == NULL) { /* * free the default manager epv if copied on register */ if (if_entry->copied_mepv) { RPC_MEM_FREE (if_entry->default_mepv, RPC_C_MEM_MGR_EPV); } if_entry->default_mepv = NULL; /* * walk the type info list and remove all entries */ RPC_LIST_FIRST (if_entry->type_info_list, type_info, rpc_if_type_info_p_t); while (type_info != NULL) { /* * free the mepv if copied during register */ if (type_info->copied_mepv) { RPC_MEM_FREE (type_info->mepv, RPC_C_MEM_MGR_EPV); } /* * remove this entry from the list for this interface */ RPC_LIST_REMOVE (if_entry->type_info_list, type_info); /* * save this entry and get the next one on the list */ current_type_info = type_info; RPC_LIST_FIRST (if_entry->type_info_list, type_info, rpc_if_type_info_p_t); /* * free the type info entry itself */ RPC_MEM_FREE (current_type_info, RPC_C_MEM_IF_TYPE_INFO); } } else { /* * see if this is an unregister for the default manager epv */ if (uuid_is_nil (mgr_type_uuid, status)) { if (if_entry->default_mepv == NULL) { *status = rpc_s_unknown_mgr_type; return; } /* * free the default manager epv if copied on register */ if (if_entry->copied_mepv) { RPC_MEM_FREE (if_entry->default_mepv, RPC_C_MEM_MGR_EPV); } if_entry->default_mepv = NULL; } else { /* * walk the type info list looking for matches */ RPC_LIST_FIRST (if_entry->type_info_list, type_info, rpc_if_type_info_p_t); while (type_info != NULL) { /* * only remove entries whose type uuid's match the one specified */ if (UUID_EQ (type_info->type, *mgr_type_uuid, status)) { /* * free the mepv if copied during register */ if (type_info->copied_mepv) { RPC_MEM_FREE (type_info->mepv, RPC_C_MEM_MGR_EPV); } /* * remove this entry from the list for this interface */ RPC_LIST_REMOVE (if_entry->type_info_list, type_info); /* * free the type info entry itself */ RPC_MEM_FREE (type_info, RPC_C_MEM_IF_TYPE_INFO); /* * then stop the search */ break; } RPC_LIST_NEXT (type_info, type_info, rpc_if_type_info_p_t); } if (type_info == NULL) { *status = rpc_s_unknown_mgr_type; return; } } } *status = rpc_s_ok; return; } /* **++ ** ** ROUTINE NAME: rpc__if_lookup ** ** SCOPE: PRIVATE - declared in comif.h ** ** DESCRIPTION: ** ** Look into the Interface Registry Table for the Interface requested. ** The search is conducted in either one or two steps. First the index ** from a previous request that is remembered in 'ihint' is tried, then ** if this fails to locate the interface, a regular hash lookup is performed. ** If the interface can't be located 'rpc_s_unknown_if' is returned. ** ** Once the interface is located, its attached linked list of type UUIDs ** is searched for the type UUID specified. If the requested type uuid ** is not found 'rpc_s_unknown_mgr_type' is returned. Once the requested ** interface and type UUID are located a pointer to the interface ** specification is returned. Also returned are the server stub epv ** and the manager epv. The index to this Interface registry is saved in ** the location pointed to by 'ihint', under the assumption that a subsequent ** lookup may request this same interface. ** ** INPUTS: ** ** if_uuid The interface UUID to lookup ** ** if_vers The interface version to lookup ** ** mgr_type_uuid The interface type (if any) ** (set this to NULL or the nil uuid to cause the ** default manager epv to be returned) ** ** INPUTS/OUTPUTS: ** ** ihint A hint of the index into the table for this if ** ** OUTPUTS: ** ** ifspec_h Pointer to the ifspec ** (NULL on input if not wanted) ** ** sepv The server stub epv for this interface ** (NULL on input if not wanted) ** ** mepv The manager epv for this interface ** (NULL on input if not wanted) ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_unknown_if ** rpc_s_unknown_mgr_type ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__if_lookup ( uuid_p_t if_uuid, unsigned32 if_vers, uuid_p_t mgr_type_uuid, unsigned16 *ihint, rpc_if_rep_p_t *ifspec, rpc_v2_server_stub_epv_t *sepv, rpc_mgr_epv_t *mepv, unsigned32 *status ) { return rpc__if_lookup2 (if_uuid, if_vers, mgr_type_uuid, ihint, ifspec, sepv, mepv, NULL, NULL, NULL, NULL, status); } /* **++ ** ** ROUTINE NAME: rpc__if_lookup2 ** ** SCOPE: PRIVATE - declared in comif.h ** ** DESCRIPTION: ** ** Look into the Interface Registry Table for the Interface requested. ** The search is conducted in either one or two steps. First the index ** from a previous request that is remembered in 'ihint' is tried, then ** if this fails to locate the interface, a regular hash lookup is performed. ** If the interface can't be located 'rpc_s_unknown_if' is returned. ** ** Once the interface is located, its attached linked list of type UUIDs ** is searched for the type UUID specified. If the requested type uuid ** is not found 'rpc_s_unknown_mgr_type' is returned. Once the requested ** interface and type UUID are located a pointer to the interface ** specification is returned. Also returned are the server stub epv ** and the manager epv. The index to this Interface registry is saved in ** the location pointed to by 'ihint', under the assumption that a subsequent ** lookup may request this same interface. ** ** INPUTS: ** ** if_uuid The interface UUID to lookup ** ** if_vers The interface version to lookup ** ** mgr_type_uuid The interface type (if any) ** (set this to NULL or the nil uuid to cause the ** default manager epv to be returned) ** ** INPUTS/OUTPUTS: ** ** ihint A hint of the index into the table for this if ** ** OUTPUTS: ** ** ifspec_h Pointer to the ifspec ** (NULL on input if not wanted) ** ** sepv The server stub epv for this interface ** (NULL on input if not wanted) ** ** mepv The manager epv for this interface ** (NULL on input if not wanted) ** ** flags The interface registration flags ** (NULL on input if not wanted) ** ** max_calls The maximum number of concurrent RPCs ** (NULL on input if not wanted) ** ** max_rpc_size The maximum size of incoming data blocks ** (NULL on input if not wanted) ** ** if_callback The security callback function ** (NULL on input if not wanted) ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_unknown_if ** rpc_s_unknown_mgr_type ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__if_lookup2 ( uuid_p_t if_uuid, unsigned32 if_vers, uuid_p_t mgr_type_uuid, unsigned16 *ihint, rpc_if_rep_p_t *ifspec, rpc_v2_server_stub_epv_t *sepv, rpc_mgr_epv_t *mepv, unsigned32 *flags, unsigned32 *max_calls, unsigned32 *max_rpc_size, rpc_if_callback_fn_t *if_callback, unsigned32 *status ) { rpc_if_rgy_entry_p_t if_entry = NULL; rpc_if_type_info_p_t type_info; unsigned32 index; unsigned32 entry_count = 0; unsigned32 temp_status; RPC_LOG_IF_LOOKUP_NTR; CODING_ERROR (status); /* * take out a lock to protect access to the if registry */ RPC_MUTEX_LOCK (if_mutex); /* * see if the interface hint we're given is valid */ if (*ihint != RPC_C_INVALID_IHINT) { /* * extract the hash value from the low byte of the ihint * and the list entry count form the high byte */ index = *ihint & 0x00FF; entry_count = (*ihint & 0xFF00) >> 8; /* * try to find a match using the hints provided */ RPC_LIST_LOOKUP (if_registry[index], if_entry, rpc_if_rgy_entry_p_t, entry_count); if (if_entry != NULL && ! RPC_IF_IS_COMPATIBLE (if_entry, if_uuid, if_vers, status)) { if_entry = NULL; } } else { /* * compute a hash value using the interface uuid - check the status * from uuid_hash to make sure the uuid has a valid format */ index = uuid_hash (if_uuid, status) % RPC_C_IF_REGISTRY_SIZE; if (*status != uuid_s_ok) { RPC_MUTEX_UNLOCK (if_mutex); return; } } /* * if we got this far and didn't find a match, search the whole list * under the current hash value for the given interface */ if (if_entry == NULL) { RPC_LIST_FIRST (if_registry[index], if_entry, rpc_if_rgy_entry_p_t); for (entry_count = 1; if_entry != NULL; entry_count++) { if (RPC_IF_IS_COMPATIBLE (if_entry, if_uuid, if_vers, status)) { break; } RPC_LIST_NEXT (if_entry, if_entry, rpc_if_rgy_entry_p_t); } } /* * if still no entry was found, report unknown interface */ if (if_entry == NULL) { *ihint = RPC_C_INVALID_IHINT; *status = rpc_s_unknown_if; RPC_MUTEX_UNLOCK (if_mutex); return; } /* * if a manager type uuid is given, and is not the nil uuid, try to match * for a registered type - otherwise, return the default manager epv */ if (mgr_type_uuid != NULL && !(uuid_is_nil (mgr_type_uuid, status))) { /* * scan the type uuid/mgr epv list for a match */ RPC_LIST_FIRST (if_entry->type_info_list, type_info, rpc_if_type_info_p_t); while (type_info != NULL) { if (UUID_EQ (type_info->type, *mgr_type_uuid, status)) { if (mepv != NULL) { *mepv = type_info->mepv; } break; } RPC_LIST_NEXT (type_info, type_info, rpc_if_type_info_p_t); } if (type_info == NULL) { /* * if no 'type' match is found, invalidate the interface * hint. But before giving up entirely, if the interface * we're looking for is the internal mgmt interface, try * one more time using a NIL type; this lets clients make * remote mgmt calls using bindings that might have a typed * object in them. */ *ihint = RPC_C_INVALID_IHINT; *status = rpc_s_unknown_mgr_type; RPC_MUTEX_UNLOCK (if_mutex); if (UUID_EQ (((rpc_if_rep_p_t) mgmt_v1_0_s_ifspec)->id, *if_uuid, &temp_status)) { rpc__if_lookup2 (if_uuid, if_vers, NULL, ihint, ifspec, sepv, mepv, flags, max_calls, max_rpc_size, if_callback, status); } return; } } else { /* * The default (nil-type) manager epv is requested, * return an error if one isn't registered and a manager epv * is wanted. */ if (mepv != NULL) { if (if_entry->default_mepv == NULL) { *ihint = RPC_C_INVALID_IHINT; *status = rpc_s_unknown_mgr_type; RPC_MUTEX_UNLOCK (if_mutex); return; } *mepv = if_entry->default_mepv; } } /* * if a complete match is found, return its info (if wanted) */ if (ifspec != NULL) { *ifspec = if_entry->if_spec; } if (sepv != NULL) { *sepv = if_entry->if_spec->server_epv; } if (flags != NULL) { *flags = if_entry->flags; } if (max_calls != NULL) { *max_calls = if_entry->max_calls; } if (max_rpc_size != NULL) { *max_rpc_size = if_entry->max_rpc_size; } if (if_callback != NULL) { *if_callback = if_entry->if_callback; } /* * provide a useful hint for future references to this interface */ *ihint = (unsigned16) (index | ((entry_count & 0x00FF) << 8)); RPC_MUTEX_UNLOCK (if_mutex); *status = rpc_s_ok; RPC_LOG_IF_LOOKUP_XIT; return; } /* **++ ** ** ROUTINE NAME: rpc_if_inq_id ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** Extract the interface id (UUID and version numbers) from the given ** interface spec. ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** if_id The interface id. ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PUBLIC void rpc_if_inq_id ( rpc_if_handle_t ifspec_h, rpc_if_id_t *if_id, unsigned32 *status ) { CODING_ERROR (status); RPC_VERIFY_INIT (); /* * copy the interface UUID from the if_spec */ if_id->uuid = ((rpc_if_rep_p_t) (ifspec_h))->id; /* * convert the old form of the version number (single unsigned long) * into the new form (major and minor unsigned16's) */ if_id->vers_major = RPC_IF_VERS_MAJOR(((rpc_if_rep_p_t) ifspec_h)->vers); if_id->vers_minor = RPC_IF_VERS_MINOR(((rpc_if_rep_p_t) (ifspec_h))->vers); *status = rpc_s_ok; } /* **++ ** ** ROUTINE NAME: rpc__if_id_compare ** ** SCOPE: PRIVATE - declared in com.h ** ** DESCRIPTION: ** ** Compares two interface id's and matches based on the version option. ** ** INPUTS: ** ** if_id_ref The reference interface id against which the comparison ** is to be made. ** ** if_id The interface id to be compared to the reference. ** ** if_vers_option The criteria by which the if version numbers are to ** be compared. One of: ** rpc_c_vers_all ** rpc_c_vers_compatible ** rpc_c_vers_exact ** rpc_c_vers_major_only ** rpc_c_vers_upto ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** status The result of the operation. One of: ** rpc_s_ok ** the result of uuid_equal() ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: ** ** true if the interface id is compatible with the reference ** false if the interface id is not compatible with the reference ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE boolean rpc__if_id_compare ( rpc_if_id_p_t if_id_ref, rpc_if_id_p_t if_id, unsigned32 if_vers_option, unsigned32 *status ) { *status = rpc_s_ok; /* * see if the returned if uuid matches the one given */ if (! (UUID_EQ (if_id->uuid, if_id_ref->uuid, status))) { /* * return "incompatible" and the status of uuid_equal() */ return (false); } else { /* * if they do match, check what the version option is */ switch ((int)if_vers_option) { /* * any version is ok */ case rpc_c_vers_all: { return (true); } /* * major versions must match, minor version must be greater than * or equal to minor version in the reference */ case rpc_c_vers_compatible: { if (if_id->vers_major == if_id_ref->vers_major && if_id->vers_minor >= if_id_ref->vers_minor) { return (true); } else { return (false); } } /* * major and minor versions must match */ case rpc_c_vers_exact: { if (if_id->vers_major == if_id_ref->vers_major && if_id->vers_minor == if_id_ref->vers_minor) { return (true); } else { return (false); } } /* * major versions must match - minor versions are ignored */ case rpc_c_vers_major_only: { if (if_id->vers_major == if_id_ref->vers_major) { return (true); } else { return (false); } } /* * major version and minor version must both be less than or * equal to their counterparts in the reference */ case rpc_c_vers_upto: { if (if_id->vers_major < if_id_ref->vers_major) { return (true); } else { if (if_id->vers_major == if_id_ref->vers_major && if_id->vers_minor <= if_id_ref->vers_minor) { return (true); } else { return (false); } } } } return (false); } } /* **++ ** ** ROUTINE NAME: rpc_if_id_vector_free ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** Free the memory allocated for an rpc_if_id_vector_t. ** ** INPUTS: none ** ** INPUTS/OUTPUTS: ** ** if_id_vector The vector of interface id's to be freed. ** ** OUTPUTS: ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_coding_error ** rpc_s_invalid_arg ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PUBLIC void rpc_if_id_vector_free ( rpc_if_id_vector_p_t *if_id_vector, unsigned32 *status ) { unsigned32 i; CODING_ERROR (status); RPC_VERIFY_INIT (); /* * check to see if if_id_vector is NULL, and if * so, return an error status */ if (if_id_vector == NULL) { *status = rpc_s_invalid_arg; return; } /* * walk the if id vector and free each element */ for (i = 0; i < (*if_id_vector)->count; i++) { if ((*if_id_vector)->if_id[i] != NULL) { RPC_MEM_FREE ((*if_id_vector)->if_id[i], RPC_C_MEM_IF_ID); } } /* * then free the vector itself */ RPC_MEM_FREE ((*if_id_vector), RPC_C_MEM_IF_ID_VECTOR); /* * return a NULL pointer */ *if_id_vector = NULL; *status = rpc_s_ok; return; } /* **++ ** ** ROUTINE NAME: rpc__if_inq_endpoint ** ** SCOPE: PRIVATE - declared in comif.h ** ** DESCRIPTION: ** ** With the given interface spec, search through the associated array ** of RPC Protocol Sequence/endpoint pairs. Compare the Protocol Sequence ** ID given to the one in the ifspec (protocol_id's are used instead ** of protseq id strings to make handling of aliases simpler and ** localized). Filter out any extraneous info, such as "endpoint=" and ** other information the user may have put into the endpoint attribute in ** the idl file. If the requested endpoint can't be located, return ** 'rpc_s_endpoint_not_found'. ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** protseq_id The protocol sequence to be matched ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** endpoint The endpoint contained int he ifspec for the ** given protocol sequence. ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_endpoint_not_found ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__if_inq_endpoint ( rpc_if_rep_p_t ifspec, rpc_protseq_id_t protseq_id, unsigned_char_t **endpoint, unsigned32 *status ) { unsigned16 ctr; rpc_protseq_id_t pseq_id; unsigned_char_t *scratch_endpoint; CODING_ERROR (status); for (ctr = 0; ctr < ifspec->endpoint_vector.count; ctr++) { pseq_id = rpc__network_pseq_id_from_pseq ( ifspec->endpoint_vector.endpoint_vector_elt[ctr].rpc_protseq, status); if (*status == rpc_s_protseq_not_supported) { *status = rpc_s_ok; continue; } if (*status != rpc_s_ok) { return; } if (pseq_id == protseq_id) { size_t len; /* * Allocate enough space so we can place brackets around the * string before attempting to filter it. We need 3 extra * bytes, for '[', ']', and '\0'. */ len = strlen ((char *) ifspec->endpoint_vector.endpoint_vector_elt[ctr].endpoint) + 3; RPC_MEM_ALLOC ( scratch_endpoint, unsigned_char_p_t, len, RPC_C_MEM_STRING, RPC_C_MEM_WAITOK); snprintf ((char *) scratch_endpoint, len, "[%s]", (char *) (ifspec->endpoint_vector.endpoint_vector_elt[ctr].endpoint)); /* * Extract just the endpoint portion. */ rpc_string_binding_parse(scratch_endpoint, NULL, NULL, NULL, endpoint, NULL, status); RPC_MEM_FREE(scratch_endpoint, RPC_C_MEM_STRING); return; } } *status = rpc_s_endpoint_not_found; } /* **++ ** ** ROUTINE NAME: rpc__if_set_wk_endpoint ** ** SCOPE: PRIVATE - declared in comif.h ** ** DESCRIPTION: ** ** Set an RPC addr's endpoint based on the well-known endpoint in the ** given ifspec, if there is one. ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** INPUTS/OUTPUTS: ** ** rpc_addr The rpc address in which to set the endpoint ** ** OUTPUTS: ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_too_many_ifs ** rpc_s_no_memory ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__if_set_wk_endpoint ( rpc_if_rep_p_t ifspec, rpc_addr_p_t *rpc_addr, unsigned32 *status ) { unsigned_char_p_t endpoint; unsigned32 temp_status; CODING_ERROR (status); /* * get the endpoint from the if spec */ rpc__if_inq_endpoint ( ifspec, (*rpc_addr)->rpc_protseq_id, &endpoint, status); if (*status == rpc_s_ok) { /* * call the naf extension service to put the endpoint in the rpc addr */ rpc__naf_addr_set_endpoint (endpoint, rpc_addr, status); rpc_string_free (&endpoint, &temp_status); } return; } /* **++ ** ** ROUTINE NAME: rpc__if_mgmt_inq_num_registered ** ** SCOPE: PRIVATE - declared in com.h ** ** DESCRIPTION: ** ** Perform a linear search through the Interface Registry Table. ** For each slot found to contain a registered Interface specification, ** increment a counter. Return the number of active slots located. ** ** INPUTS: none ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: none ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: ** ** count The number of registered interfaces. ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE unsigned32 rpc__if_mgmt_inq_num_registered( void ) { unsigned32 entry_count = 0; unsigned32 index; rpc_if_rgy_entry_p_t if_entry; /* * take out a lock to protect access to the if registry */ RPC_MUTEX_LOCK (if_mutex); /* * walk the hash table */ for (index = 0; index < RPC_C_IF_REGISTRY_SIZE; index++) { /* * walk the list under this hash entry */ RPC_LIST_FIRST (if_registry[index], if_entry, rpc_if_rgy_entry_p_t); while (if_entry != NULL) { /* * don't count internal entries */ if (! if_entry->internal) { /* * bump the count for each entry in the list */ entry_count++; } RPC_LIST_NEXT (if_entry, if_entry, rpc_if_rgy_entry_p_t); } } RPC_MUTEX_UNLOCK (if_mutex); /* * report the total number of entries found */ return (entry_count); } /* **++ ** ** ROUTINE NAME: rpc__if_mgmt_inq_if_ids ** ** SCOPE: PRIVATE - declared in com.h ** ** DESCRIPTION: ** ** Obtain the number of active entries in the Interface Registry Table. ** Then allocate enough memory to hold a vector of if_id elements. Scan ** through the Interface Registry Table and for each active interface copy ** its UUID and Version into an rpc_if_id_t element. Return a pointer, to ** the vector of info elements that have been built. ** ** INPUTS: none ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** if_info Pointer to an if id vector ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_no_interfaces ** rpc_s_no_memory ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PRIVATE void rpc__if_mgmt_inq_if_ids ( rpc_if_id_vector_p_t *if_id_vector, unsigned32 *status ) { rpc_if_rgy_entry_p_t if_entry; unsigned32 if_count; unsigned32 index; unsigned32 if_id_index; unsigned32 temp_status; CODING_ERROR (status); /* * find the number of registered interfaces */ if ((if_count = rpc__if_mgmt_inq_num_registered()) == 0) { *status = rpc_s_no_interfaces; *if_id_vector = NULL; return; } /* * allocate memory for the if id vector */ RPC_MEM_ALLOC ( *if_id_vector, rpc_if_id_vector_p_t, ((sizeof if_count) + (if_count * sizeof (rpc_if_id_p_t))), RPC_C_MEM_IF_ID_VECTOR, RPC_C_MEM_WAITOK); /* * set the count field in the vector */ (*if_id_vector)->count = if_count; /* * take out a lock to protect access to the if registry */ RPC_MUTEX_LOCK (if_mutex); /* * search through Interface Registry Table */ for (index = 0, if_id_index = 0; index < RPC_C_IF_REGISTRY_SIZE; index++) { /* * walk the list under this hash entry */ RPC_LIST_FIRST (if_registry[index], if_entry, rpc_if_rgy_entry_p_t); while (if_entry != NULL) { /* * don't report internal entries */ if (! if_entry->internal) { /* * allocate memory for the if id */ RPC_MEM_ALLOC ( (*if_id_vector)->if_id[if_id_index], rpc_if_id_p_t, sizeof (rpc_if_id_t), RPC_C_MEM_IF_ID, RPC_C_MEM_WAITOK); /* * extract the if id info for this registry entry */ rpc_if_inq_id ((rpc_if_handle_t) (if_entry->if_spec), (*if_id_vector)->if_id[if_id_index], status); if (*status != rpc_s_ok) { /* * If anything went wrong, free the vector allocated; * but first reset the count field to the right value. */ (*if_id_vector)->count = if_id_index; rpc_if_id_vector_free (if_id_vector, &temp_status); RPC_MUTEX_UNLOCK (if_mutex); return; } if_id_index++; } RPC_LIST_NEXT (if_entry, if_entry, rpc_if_rgy_entry_p_t); } } RPC_MUTEX_UNLOCK (if_mutex); *status = rpc_s_ok; return; } /* **++ ** ** ROUTINE NAME: rpc_server_inq_if ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** Given an interface spec and type ID, return the manager EPV that has ** been registered for them (if any). ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** mgr_type_uuid The interface type ** ** mgr_epv The manager epv for this interface ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PUBLIC void rpc_server_inq_if ( rpc_if_handle_t ifspec_h, uuid_p_t mgr_type_uuid, rpc_mgr_epv_t *mgr_epv, unsigned32 *status ) { rpc_if_rep_p_t ifspec = (rpc_if_rep_p_t) ifspec_h; unsigned16 ihint = RPC_C_INVALID_IHINT; CODING_ERROR (status); RPC_VERIFY_INIT (); rpc__if_lookup2 (&ifspec->id, ifspec->vers, mgr_type_uuid, &ihint, NULL, NULL, mgr_epv, NULL, NULL, NULL, NULL, status); } /* **++ ** ** ROUTINE NAME: rpc_server_register_if_ex ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** See description of "rpc__server_register_if_int". ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** mgr_type_uuid The interface type (if any) ** ** mgr_epv The manager epv for this interface ** ** flags Registration flags ** ** max_calls The maximum number of calls ** ** if_callback Security callback ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_type_already_registered ** rpc_s_no_memory ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PUBLIC void rpc_server_register_if_ex ( rpc_if_handle_t ifspec_h, uuid_p_t mgr_type_uuid, rpc_mgr_epv_t mgr_epv, unsigned32 flags, unsigned32 max_calls, rpc_if_callback_fn_t if_callback, unsigned32 *status ) { CODING_ERROR (status); RPC_VERIFY_INIT (); rpc__server_register_if_int (ifspec_h, mgr_type_uuid, mgr_epv, flags, max_calls, -1, if_callback, false, status); } /* **++ ** ** ROUTINE NAME: rpc_server_register_if_2 ** ** SCOPE: PUBLIC - declared in rpc.idl ** ** DESCRIPTION: ** ** See description of "rpc__server_register_if_int". ** ** INPUTS: ** ** ifspec_h Pointer to the ifspec ** ** mgr_type_uuid The interface type (if any) ** ** mgr_epv The manager epv for this interface ** ** flags Registration flags ** ** max_calls The maximum number of calls ** ** max_rpc_size Maximum RPC size in bytes ** ** if_callback Security callback ** ** INPUTS/OUTPUTS: none ** ** OUTPUTS: ** ** status The result of the operation. One of: ** rpc_s_ok ** rpc_s_type_already_registered ** rpc_s_no_memory ** rpc_s_coding_error ** ** IMPLICIT INPUTS: none ** ** IMPLICIT OUTPUTS: none ** ** FUNCTION VALUE: void ** ** SIDE EFFECTS: none ** **-- **/ PUBLIC void rpc_server_register_if_2 ( rpc_if_handle_t ifspec_h, uuid_p_t mgr_type_uuid, rpc_mgr_epv_t mgr_epv, unsigned32 flags, unsigned32 max_calls, unsigned32 max_rpc_size, rpc_if_callback_fn_t if_callback, unsigned32 *status ) { CODING_ERROR (status); RPC_VERIFY_INIT (); rpc__server_register_if_int (ifspec_h, mgr_type_uuid, mgr_epv, flags, max_calls, max_rpc_size, if_callback, false, status); }