/* * * (c) Copyright 1991 OPEN SOFTWARE FOUNDATION, INC. * (c) Copyright 1991 HEWLETT-PACKARD COMPANY * (c) Copyright 1991 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. * */ /* */ /* ** ** ndrui.c ** ** FACILITY: ** ** Interface Definition Language (IDL) Compiler ** ** ABSTRACT: ** ** NDR unmarshalling interpreter main module ** */ #if HAVE_CONFIG_H #include #endif #include #include #include /* * Forward function references */ /* None */ /******************************************************************************/ /* */ /* Calculate storage allocation size */ /* */ /******************************************************************************/ idl_ulong_int rpc_ss_ndr_allocation_size #ifdef IDL_PROTOTYPES ( /* [in] */ idl_ulong_int fixed_part_size, /* Size of the fixed part of the object to be allocated */ /* [in] */ idl_ulong_int dimensionality, /* 0 if object has no array part */ /* [in] */ idl_ulong_int *Z_values, /* Ignored if object has no array part */ /* [in] */ idl_byte *array_defn_ptr, /* If object has array part, points to array base info */ IDL_msp_t IDL_msp ) #else ( fixed_part_size, dimensionality, Z_values, array_defn_ptr, IDL_msp ) idl_ulong_int fixed_part_size; idl_ulong_int dimensionality; idl_ulong_int *Z_values; idl_byte *array_defn_ptr; IDL_msp_t IDL_msp; #endif { idl_ulong_int allocation_size; unsigned32 i; idl_ulong_int dummy_defn_index; /* Throw-away array parameter */ if (dimensionality == 0) allocation_size = 0; else { /* Get size of array base type */ if (*array_defn_ptr == IDL_DT_STRING) { dimensionality--; rpc_ss_get_string_base_desc(array_defn_ptr, &allocation_size, &dummy_defn_index, IDL_msp); } else allocation_size = rpc_ss_type_size(array_defn_ptr, IDL_msp); /* Multiply by number of array elements */ for (i=0; iIDL_side == IDL_server_side_k) { *p_storage_addr = (rpc_void_p_t)rpc_ss_mem_alloc(&(IDL_msp->IDL_mem_handle), allocation_size); } else { *p_storage_addr = (rpc_void_p_t)(*(IDL_msp->IDL_p_allocate)) (allocation_size); if (*p_storage_addr == NULL) DCETHREAD_RAISE(rpc_x_no_memory); } } /******************************************************************************/ /* */ /* Unmarshall a structure */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_struct #ifdef IDL_PROTOTYPES ( /* [in] */ idl_byte struct_type, /* DT_FIXED_STRUCT or DT_CONF_STRUCT */ /* [in] */ idl_byte *defn_vec_ptr, /* Points to index into offset vector */ /* [in] */ rpc_void_p_t struct_addr, /* [in] */ idl_ulong_int *Z_values, /* Only used for DT_CONF_STRUCT */ /* [in] */ IDL_cs_shadow_elt_t *cs_shadow, /* NULL unless conformant struct with cs-shadow */ IDL_msp_t IDL_msp ) #else (struct_type, defn_vec_ptr, struct_addr, Z_values, cs_shadow, IDL_msp) idl_byte struct_type; idl_byte *defn_vec_ptr; rpc_void_p_t struct_addr; idl_ulong_int *Z_values; IDL_cs_shadow_elt_t *cs_shadow; IDL_msp_t IDL_msp; #endif { idl_ulong_int offset_index; idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */ idl_ulong_int *offset_vec_ptr; idl_byte type_byte; idl_ulong_int offset; idl_ulong_int field_defn_index; idl_byte *field_defn_ptr; idl_ulong_int conf_dims; /* Number of dimensions of conformance info */ IDL_bound_pair_t *range_list; IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS]; IDL_bound_pair_t *bounds_list; IDL_bound_pair_t range_bounds; idl_ulong_int *varying_Z_values; /* Used for varying array fields */ idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS]; idl_ulong_int array_dims; /* Number of dimensions of array */ idl_ulong_int unique_flag; /* Wire form of [unique] pointer */ idl_ulong_int switch_value; /* Discarded [out] parameter */ intptr_t node_number = 0; idl_ulong_int shadow_length; idl_byte *shadow_defn_ptr = NULL; /* Position after shadow_length */ IDL_bound_pair_t *correl_bounds_list; IDL_bound_pair_t normal_correl_bounds_list[IDL_NORMAL_DIMS]; IDL_GET_LONG_FROM_VECTOR(offset_index,defn_vec_ptr); struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index; IDL_INIT_RANGE(range_bounds); if ( (struct_type == IDL_DT_CONF_STRUCT) || (struct_type == IDL_DT_V1_CONF_STRUCT) ) { /* Discard the conformance info */ IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); } if (*defn_vec_ptr == IDL_DT_CS_SHADOW) { defn_vec_ptr++; IDL_GET_LONG_FROM_VECTOR(shadow_length, defn_vec_ptr); if (cs_shadow == NULL) { cs_shadow = (IDL_cs_shadow_elt_t *) rpc_ss_mem_alloc (&IDL_msp->IDL_mem_handle, shadow_length * sizeof(IDL_cs_shadow_elt_t)); } shadow_defn_ptr = defn_vec_ptr; } offset_vec_ptr = struct_offset_vec_ptr + 1; /* Skip over size at start of offsets */ /* Loop over the fields of the structure */ do { type_byte = *defn_vec_ptr; defn_vec_ptr++; switch(type_byte) { case IDL_DT_BYTE: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_BYTE( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_BYTE( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_CHAR: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_CHAR( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_CHAR( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_BOOLEAN: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_BOOLEAN( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_BOOLEAN( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_DOUBLE: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_DOUBLE( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_DOUBLE( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_ENUM: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_ENUM( (idl_byte *)struct_addr+offset ); break; case IDL_DT_FLOAT: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_FLOAT( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_FLOAT( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_SMALL: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_SMALL( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_SMALL( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_SHORT: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_SHORT( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_SHORT( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_LONG: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_LONG( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_LONG( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_HYPER: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_HYPER( (idl_byte *)struct_addr+offset ); break; case IDL_DT_USMALL: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_USMALL( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_USMALL( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_USHORT: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_USHORT( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_USHORT( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_ULONG: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_ULONG( (idl_byte *)struct_addr+offset ); IDL_CHECK_RANGE_ULONG( range_bounds, (idl_byte *)struct_addr + offset ); break; case IDL_DT_UHYPER: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_UHYPER( (idl_byte *)struct_addr+offset ); break; case IDL_DT_V1_ENUM: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_V1_ENUM( (idl_byte *)struct_addr+offset ); break; case IDL_DT_ERROR_STATUS: offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_ERROR_STATUS( (idl_byte *)struct_addr+offset ); break; case IDL_DT_FIXED_ARRAY: defn_vec_ptr++; /* Skip over properties byte */ IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Full array definition */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; offset_vec_ptr++; rpc_ss_ndr_unmar_fixed_arr(field_defn_index, (idl_byte *)struct_addr+offset, 0, IDL_msp); break; case IDL_DT_VARYING_ARRAY: defn_vec_ptr++; /* Skip over properties byte */ IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Full array definition */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; offset_vec_ptr++; field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index; array_dims = (idl_ulong_int)*field_defn_ptr; field_defn_ptr++; /* By design field_defn_ptr is now at (0 mod 4) */ if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP) rpc_ss_fixed_bounds_from_vector(array_dims, field_defn_ptr, &bounds_list, IDL_msp); else bounds_list = (IDL_bound_pair_t *)field_defn_ptr; if (array_dims > IDL_NORMAL_DIMS) { varying_Z_values = NULL; range_list = NULL; } else { varying_Z_values = normal_Z_values; range_list = normal_range_list; } rpc_ss_Z_values_from_bounds(bounds_list, array_dims, &varying_Z_values, IDL_msp); field_defn_ptr += array_dims * IDL_FIXED_BOUND_PAIR_WIDTH; rpc_ss_ndr_unmar_range_list( array_dims, field_defn_ptr[array_dims * IDL_DATA_LIMIT_PAIR_WIDTH], &range_list, IDL_msp ); rpc_ss_ndr_unmar_check_range_correlation( &field_defn_ptr, (idl_byte *)struct_addr + offset, struct_addr, struct_offset_vec_ptr, array_dims, bounds_list, range_list, IDL_msp ); rpc_ss_ndr_u_var_or_open_arr( array_dims, varying_Z_values, field_defn_ptr, (idl_byte *)struct_addr+offset, range_list, 0, IDL_msp ); if (array_dims > IDL_NORMAL_DIMS) { rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)range_list); rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)varying_Z_values); } if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list); break; case IDL_DT_CONF_ARRAY: defn_vec_ptr++; /* Skip over properties byte */ IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Full array definition */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; /* Must be last field of struct */ field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index; conf_dims = (idl_ulong_int)*field_defn_ptr; field_defn_ptr++; rpc_ss_ndr_unmar_check_bounds_correlation( &field_defn_ptr, (rpc_void_p_t)((idl_byte *)struct_addr + offset), struct_addr, struct_offset_vec_ptr, conf_dims, Z_values, NULL, IDL_msp ); rpc_ss_ndr_u_fix_or_conf_arr( conf_dims, Z_values, field_defn_ptr, (idl_byte *)struct_addr+offset, IDL_M_CONF_ARRAY, IDL_msp ); break; case IDL_DT_OPEN_ARRAY: defn_vec_ptr++; /* Skip over properties byte */ IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Full array definition */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; /* Must be last field of struct */ field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index; conf_dims = (idl_ulong_int)*field_defn_ptr; field_defn_ptr++; if (conf_dims > IDL_NORMAL_DIMS) { correl_bounds_list = NULL; range_list = NULL; } else { correl_bounds_list = normal_correl_bounds_list; range_list = normal_range_list; } rpc_ss_ndr_unmar_check_bounds_correlation( &field_defn_ptr, (rpc_void_p_t)((idl_byte *)struct_addr + offset), struct_addr, struct_offset_vec_ptr, conf_dims, Z_values, &correl_bounds_list, IDL_msp ); rpc_ss_ndr_unmar_range_list( conf_dims, field_defn_ptr[conf_dims * IDL_DATA_LIMIT_PAIR_WIDTH], &range_list, IDL_msp ); rpc_ss_ndr_unmar_check_range_correlation( &field_defn_ptr, (rpc_void_p_t)((idl_byte *)struct_addr + offset), struct_addr, struct_offset_vec_ptr, conf_dims, correl_bounds_list, range_list, IDL_msp ); rpc_ss_ndr_u_var_or_open_arr( conf_dims, Z_values, field_defn_ptr, (idl_byte *)struct_addr+offset, range_list, IDL_M_CONF_ARRAY, IDL_msp ); if (conf_dims > IDL_NORMAL_DIMS) { rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)correl_bounds_list); rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)range_list); } break; case IDL_DT_ENC_UNION: defn_vec_ptr++; /* Skip over properties byte */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; offset_vec_ptr++; rpc_ss_ndr_u_enc_union_or_ptees( (idl_byte *)struct_addr+offset, field_defn_index, idl_false, IDL_msp); break; case IDL_DT_N_E_UNION: defn_vec_ptr++; /* Skip over properties byte */ IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Switch index */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; offset_vec_ptr++; rpc_ss_ndr_unmar_n_e_union( (idl_byte *)struct_addr+offset, field_defn_index, &switch_value, IDL_msp); break; case IDL_DT_FULL_PTR: { idl_ulong_int _node; defn_vec_ptr++; /* Properties byte */ /* Unmarshall the node number into the space for the pointer */ offset = *offset_vec_ptr; offset_vec_ptr++; IDL_UNMAR_ULONG( &_node ); node_number = (intptr_t) _node; *(rpc_void_p_t *)((idl_byte *)struct_addr+offset) = (rpc_void_p_t)node_number; IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Indirection to pointee type */ break; } case IDL_DT_UNIQUE_PTR: defn_vec_ptr++; /* Properties byte */ IDL_UNMAR_ULONG( &unique_flag ); IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Indirection to pointee type */ offset = *offset_vec_ptr; offset_vec_ptr++; if (unique_flag == 0) { *(rpc_void_p_t *)((idl_byte *)struct_addr+offset) = NULL; } else { *(rpc_void_p_t *)((idl_byte *)struct_addr+offset) = IDL_NEW_NODE; } break; case IDL_DT_REF_PTR: defn_vec_ptr++; /* Properties byte */ /* Skip over the longword place holder */ IDL_UNMAR_ALIGN_MP( IDL_msp, 4 ); rpc_ss_ndr_unmar_check_buffer( IDL_msp ); IDL_msp->IDL_mp += 4; IDL_msp->IDL_left_in_buff -= 4; IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Indirection to pointee type */ offset_vec_ptr++; break; case IDL_DT_IGNORE: /* Skip over the longword place holder */ IDL_UNMAR_ALIGN_MP( IDL_msp, 4 ); rpc_ss_ndr_unmar_check_buffer( IDL_msp ); IDL_msp->IDL_mp += 4; IDL_msp->IDL_left_in_buff -= 4; offset_vec_ptr++; break; case IDL_DT_STRING: /* Varying/open array code will do the right thing */ break; case IDL_DT_TRANSMIT_AS: case IDL_DT_REPRESENT_AS: defn_vec_ptr++; /* Skip over properties byte */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; offset_vec_ptr++; rpc_ss_ndr_unmar_xmit_as(field_defn_index, (idl_byte *)struct_addr+offset, NULL, IDL_msp); break; #if 0 case IDL_DT_INTERFACE: defn_vec_ptr++; /* Skip over properties byte */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; offset_vec_ptr++; rpc_ss_ndr_unmar_interface(field_defn_index, (idl_byte *)struct_addr+offset, NULL, IDL_msp); break; #endif case IDL_DT_V1_ARRAY: type_byte = *defn_vec_ptr; /* DT_VARYING or DT_OPEN */ defn_vec_ptr += 2; /* DT_VARYING/DT_OPEN and properties */ IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Full array definition */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; offset_vec_ptr++; field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index; array_dims = (idl_ulong_int)*field_defn_ptr; field_defn_ptr++; /* By design field_defn_ptr is now at (0 mod 4) */ if (type_byte == IDL_DT_VARYING_ARRAY) { field_defn_ptr += array_dims * (IDL_FIXED_BOUND_PAIR_WIDTH + IDL_DATA_LIMIT_PAIR_WIDTH); } else { IDL_ADV_DEFN_PTR_OVER_BOUNDS( field_defn_ptr, array_dims ); /* Advance array defn ptr over data limit info */ field_defn_ptr += array_dims * IDL_DATA_LIMIT_PAIR_WIDTH; } rpc_ss_ndr_u_v1_varying_arr( (idl_byte *)struct_addr+offset, field_defn_ptr, 0, IDL_msp ); break; case IDL_DT_V1_STRING: defn_vec_ptr += 2; /* DT_VARYING_ARRAY and properties */ IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Full array defn */ IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Flattened array defn */ offset = *offset_vec_ptr; offset_vec_ptr++; rpc_ss_ndr_unmar_v1_string((idl_byte *)struct_addr+offset, 0, IDL_msp); break; case IDL_DT_CS_ATTRIBUTE: /* Discard the value on the wire. Later a correct value will be written from the cs-shadow */ rpc_ss_ndr_unmar_scalar(*defn_vec_ptr, (rpc_void_p_t)&switch_value, IDL_msp); defn_vec_ptr++; /* Type of attribute */ offset_vec_ptr++; break; case IDL_DT_CS_ARRAY: offset = *offset_vec_ptr; rpc_ss_ndr_unmar_cs_array( (rpc_void_p_t)((idl_byte *)struct_addr+offset), cs_shadow, Z_values, offset_vec_ptr - (struct_offset_vec_ptr + 1), &defn_vec_ptr, IDL_msp); offset_vec_ptr++; break; case IDL_DT_CS_TYPE: defn_vec_ptr++; /* Skip over properties byte */ IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr); offset = *offset_vec_ptr; offset_vec_ptr++; rpc_ss_ndr_unmar_cs_char( (rpc_void_p_t)((idl_byte *)struct_addr+offset), field_defn_index, IDL_msp); break; case IDL_DT_CS_RLSE_SHADOW: rpc_ss_ndr_u_struct_cs_shadow(struct_addr, struct_type, offset_index, shadow_defn_ptr, cs_shadow, IDL_msp); break; case IDL_DT_NDR_ALIGN_2: IDL_UNMAR_ALIGN_MP( IDL_msp, 2 ); break; case IDL_DT_NDR_ALIGN_4: IDL_UNMAR_ALIGN_MP( IDL_msp, 4 ); break; case IDL_DT_NDR_ALIGN_8: IDL_UNMAR_ALIGN_MP( IDL_msp, 8 ); break; case IDL_DT_RANGE: IDL_GET_RANGE_FROM_VECTOR( range_bounds, defn_vec_ptr ); break; case IDL_DT_BEGIN_NESTED_STRUCT: case IDL_DT_END_NESTED_STRUCT: case IDL_DT_EOL: break; default: #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_struct:unrecognized type %d\n", type_byte); exit(0); #endif DCETHREAD_RAISE(rpc_x_coding_error); } } while (type_byte != IDL_DT_EOL); } /******************************************************************************/ /* */ /* Unmarshall an array by copying from the receive buffer */ /* On entry IDL_mp is already aligned to the base type requirement */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_by_copying #ifdef IDL_PROTOTYPES ( /* [in] */ idl_ulong_int element_count, /* [in] */ idl_ulong_int element_size, /* [in] */ rpc_void_p_t array_addr, IDL_msp_t IDL_msp ) #else ( element_count, element_size, array_addr, IDL_msp ) idl_ulong_int element_count; idl_ulong_int element_size; rpc_void_p_t array_addr; IDL_msp_t IDL_msp; #endif { idl_ulong_int bytes_required; /* Number of bytes left to copy */ idl_ulong_int bytes_to_copy; /* Number of bytes to copy from this buffer */ bytes_required = element_count * element_size; while (bytes_required != 0) { rpc_ss_ndr_unmar_check_buffer( IDL_msp ); if (bytes_required > IDL_msp->IDL_left_in_buff) bytes_to_copy = IDL_msp->IDL_left_in_buff; else bytes_to_copy = bytes_required; memcpy(array_addr, IDL_msp->IDL_mp, bytes_to_copy); IDL_msp->IDL_mp += bytes_to_copy; IDL_msp->IDL_left_in_buff -= bytes_to_copy; bytes_required -= bytes_to_copy; array_addr = (rpc_void_p_t)((idl_byte *)array_addr + bytes_to_copy); } } /******************************************************************************/ /* */ /* Unmarshall a contiguous set of elements one by one */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_by_looping #ifdef IDL_PROTOTYPES ( /* [in] */ idl_ulong_int element_count, /* [in] */ idl_byte base_type, /* [in] */ rpc_void_p_t array_addr, /* [in] */ idl_ulong_int element_size, /* Used if array of struct, union or array of string */ /* [in] */ idl_ulong_int element_defn_index, /* Used if array of struct or array of string */ IDL_msp_t IDL_msp ) #else (element_count, base_type, array_addr, element_size, element_defn_index, IDL_msp) idl_ulong_int element_count; idl_byte base_type; rpc_void_p_t array_addr; idl_ulong_int element_size; idl_ulong_int element_defn_index; IDL_msp_t IDL_msp; #endif { unsigned32 i; idl_ulong_int unique_flag; /* Wire form of [unique] pointer */ idl_ulong_int element_byte_count; /* Number of bytes elements occupy */ intptr_t node_number = 0; idl_byte *element_defn_ptr; unsigned long xmit_data_size; /* [transmit_as] - size of xmitted type */ rpc_void_p_t xmit_data_buff = NULL; /* Address of storage [transmit_as] type can be unmarshalled into */ if (base_type == IDL_DT_REF_PTR) { /* Unmarshalling field which is array of [ref] pointers */ IDL_UNMAR_ALIGN_MP( IDL_msp, 4 ); while (element_count > 0) { element_byte_count = 4 * element_count; if ( element_byte_count > IDL_msp->IDL_left_in_buff ) { element_count -= IDL_msp->IDL_left_in_buff / 4; /* Force a buffer change */ rpc_ss_ndr_unmar_check_buffer( IDL_msp ); } else { IDL_msp->IDL_mp += element_byte_count; IDL_msp->IDL_left_in_buff -= element_byte_count; element_count = 0; } } return; } if ( (base_type == IDL_DT_TRANSMIT_AS) || (base_type == IDL_DT_REPRESENT_AS) ) { /* If possible, allocate a buffer into which elements of the transmitted type can be unmarshalled */ element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index; IDL_DISCARD_LONG_FROM_VECTOR( element_defn_ptr ); /* Presented type size index */ IDL_DISCARD_LONG_FROM_VECTOR( element_defn_ptr ); /* Rtn vec index */ if (*element_defn_ptr == IDL_DT_STRING) element_defn_ptr++; xmit_data_size = rpc_ss_type_size(element_defn_ptr, IDL_msp); if (xmit_data_size != 0) xmit_data_buff = (rpc_void_p_t)rpc_ss_mem_alloc (&IDL_msp->IDL_mem_handle, xmit_data_size); } for (i=0; iIDL_type_vec + element_defn_index, array_addr, NULL, NULL, IDL_msp ); array_addr = (rpc_void_p_t) ((idl_byte *)(array_addr) + element_size); break; case IDL_DT_FIXED_ARRAY: /* Base type of pipe is array */ rpc_ss_ndr_unmar_fixed_arr( element_defn_index, array_addr, 0, IDL_msp ); array_addr = (rpc_void_p_t) ((idl_byte *)(array_addr) + element_size); break; case IDL_DT_ENC_UNION: rpc_ss_ndr_u_enc_union_or_ptees( array_addr, element_defn_index, idl_false, IDL_msp ); array_addr = (rpc_void_p_t) ((idl_byte *)(array_addr) + element_size); break; case IDL_DT_FULL_PTR: { idl_ulong_int _node; /* Unmarshall the node number into the space for the pointer */ IDL_UNMAR_ULONG( &_node ); node_number = (intptr_t) _node; *(rpc_void_p_t *)(array_addr) = (rpc_void_p_t)node_number; array_addr = (rpc_void_p_t)((rpc_void_p_t *)(array_addr) + 1); break; } case IDL_DT_UNIQUE_PTR: IDL_UNMAR_ULONG( &unique_flag ); if (unique_flag == 0) *(rpc_void_p_t *)array_addr = NULL; else if ( *(rpc_void_p_t *)array_addr == NULL ) *(rpc_void_p_t *)array_addr = IDL_NEW_NODE; array_addr = (rpc_void_p_t)((rpc_void_p_t *)(array_addr) + 1); break; case IDL_DT_STRING: { idl_byte *element_defn_ptr; idl_ulong_int A, B; idl_ulong_int base_type_size; element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index + 1 /* Dimensionality */ + IDL_FIXED_BOUND_PAIR_WIDTH + IDL_DATA_LIMIT_PAIR_WIDTH; /* Now pointing at base type of string */ base_type_size = rpc_ss_type_size(element_defn_ptr, IDL_msp); IDL_UNMAR_ALIGN_MP( IDL_msp, 4 ); rpc_ss_ndr_unmar_check_buffer( IDL_msp ); rpc_convert_ulong_int(IDL_msp->IDL_drep, ndr_g_local_drep, IDL_msp->IDL_mp, A); IDL_msp->IDL_mp += 4; IDL_msp->IDL_left_in_buff -= 4; rpc_ss_ndr_unmar_check_buffer( IDL_msp ); rpc_convert_ulong_int(IDL_msp->IDL_drep, ndr_g_local_drep, IDL_msp->IDL_mp, B); IDL_msp->IDL_mp += 4; IDL_msp->IDL_left_in_buff -= 4; if ( ( (*element_defn_ptr == IDL_DT_CHAR) && (IDL_msp->IDL_drep.char_rep != ndr_g_local_drep.char_rep) ) || ( (*element_defn_ptr == IDL_DT_USHORT || *element_defn_ptr == IDL_DT_ULONG) && (IDL_msp->IDL_drep.int_rep != ndr_g_local_drep.int_rep) ) ) { rpc_ss_ndr_unmar_by_looping(B, *element_defn_ptr, array_addr, 1, 0, IDL_msp); } else rpc_ss_ndr_unmar_by_copying(B, base_type_size, array_addr, IDL_msp); } array_addr = (rpc_void_p_t) ((idl_byte *)(array_addr) + element_size); break; case IDL_DT_TRANSMIT_AS: case IDL_DT_REPRESENT_AS: rpc_ss_ndr_unmar_xmit_as(element_defn_index, array_addr, xmit_data_buff, IDL_msp); array_addr = (rpc_void_p_t) ((idl_byte *)(array_addr) + element_size); break; case IDL_DT_V1_STRING: rpc_ss_ndr_unmar_v1_string(array_addr, 0, IDL_msp); array_addr = (rpc_void_p_t) ((idl_byte *)(array_addr) + element_size); break; default: #ifdef DEBUG_INTERP printf( "rpc_ss_ndr_unmar_by_looping:unrecognized type %d\n", base_type); exit(0); #endif DCETHREAD_RAISE(rpc_x_coding_error); } } if (xmit_data_buff != NULL) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,(byte_p_t)xmit_data_buff); } /******************************************************************************/ /* */ /* Unmarshall a fixed or conformant array */ /* */ /******************************************************************************/ void rpc_ss_ndr_u_fix_or_conf_arr #ifdef IDL_PROTOTYPES ( /* [in] */ idl_ulong_int dimensionality, /* [in] */ idl_ulong_int *Z_values, /* [in] */ idl_byte *defn_vec_ptr, /* On entry points to array base info */ /* [in] */ rpc_void_p_t array_addr, /* [in] */ idl_ulong_int flags ATTRIBUTE_UNUSED, IDL_msp_t IDL_msp ) #else ( dimensionality, Z_values, defn_vec_ptr, array_addr, flags, IDL_msp ) idl_ulong_int dimensionality; idl_ulong_int *Z_values; idl_byte *defn_vec_ptr; rpc_void_p_t array_addr; idl_ulong_int flags; IDL_msp_t IDL_msp; #endif { idl_ulong_int element_count; unsigned32 i; idl_byte base_type; idl_boolean unmarshall_by_copying; idl_ulong_int element_size; idl_ulong_int element_defn_index; idl_ulong_int struct_offset_index; idl_byte *struct_defn_ptr; if ( (*defn_vec_ptr == IDL_DT_STRING) || (*defn_vec_ptr == IDL_DT_V1_STRING) ) { /* Arrays of strings have a special representation */ dimensionality--; } element_count = 1; for (i=0; iIDL_type_vec + element_defn_index, (rpc_void_p_t)((idl_byte *)array_addr + element_count * element_size), NULL, NULL, IDL_msp); } return; } if ( (base_type == IDL_DT_FIXED_STRUCT) || (base_type == IDL_DT_ENC_UNION) || (base_type == IDL_DT_TRANSMIT_AS) || (base_type == IDL_DT_REPRESENT_AS) ) { defn_vec_ptr += 2; /* Discard type and properties */ /* If we are unmarshalling an array, not a pipe, defn_vec_ptr was 4-byte aligned and DT_MODIFIED and modifier are discarded by the +=2 followed by GET_LONG */ IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr ); struct_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index; IDL_GET_LONG_FROM_VECTOR(struct_offset_index, struct_defn_ptr); element_size = *(IDL_msp->IDL_offset_vec + struct_offset_index); } else if ( (base_type == IDL_DT_STRING) || (base_type == IDL_DT_V1_STRING) ) { rpc_ss_get_string_base_desc( defn_vec_ptr, &element_size, &element_defn_index, IDL_msp ); } else if (base_type == IDL_DT_FIXED_ARRAY) { /* Base type of pipe is array */ element_size = rpc_ss_type_size( defn_vec_ptr, IDL_msp ); defn_vec_ptr += 2; /* Base type and properties byte */ IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Full array defn */ IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr ); } else if (base_type == IDL_DT_INTERFACE) { element_size = sizeof(void*); defn_vec_ptr += 2; /* skip base type and props */ IDL_GET_LONG_FROM_VECTOR(element_defn_index, defn_vec_ptr); } else element_defn_index = 0; rpc_ss_ndr_unmar_by_looping( element_count, base_type, array_addr, element_size, element_defn_index, IDL_msp); } /******************************************************************************/ /* */ /* Unmarshall a fixed array */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_fixed_arr #ifdef IDL_PROTOTYPES ( /* [in] */ idl_ulong_int defn_index, /* [in] */ rpc_void_p_t array_addr, /* [in] */ idl_ulong_int flags, IDL_msp_t IDL_msp ) #else (defn_index, array_addr, flags, IDL_msp) idl_ulong_int defn_index; rpc_void_p_t array_addr; idl_ulong_int flags; IDL_msp_t IDL_msp; #endif { idl_byte *defn_vec_ptr; idl_ulong_int dimensionality; idl_ulong_int *Z_values; idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS]; IDL_bound_pair_t *bounds_list; defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index; dimensionality = (idl_ulong_int)*defn_vec_ptr; defn_vec_ptr++; /* By design, alignment is now (0 mod 4) */ if (dimensionality > IDL_NORMAL_DIMS) Z_values = NULL; else Z_values = normal_Z_values; if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP) rpc_ss_fixed_bounds_from_vector(dimensionality, defn_vec_ptr, &bounds_list, IDL_msp); else bounds_list = (IDL_bound_pair_t *)defn_vec_ptr; rpc_ss_Z_values_from_bounds( bounds_list, dimensionality, &Z_values, IDL_msp ); defn_vec_ptr += dimensionality * IDL_FIXED_BOUND_PAIR_WIDTH; rpc_ss_ndr_u_fix_or_conf_arr( dimensionality, Z_values, defn_vec_ptr, array_addr, flags, IDL_msp); if (dimensionality > IDL_NORMAL_DIMS) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values); if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list); } /******************************************************************************/ /* */ /* Unmarshall A,B pairs and build a range list from them */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_range_list #ifdef IDL_PROTOTYPES ( /* [in] */ idl_ulong_int dimensionality, /* [in] */ idl_byte base_type, /* Base type of the varying array */ /* [out] */ IDL_bound_pair_t **p_range_list, IDL_msp_t IDL_msp ) #else ( dimensionality, base_type, p_range_list, IDL_msp ) idl_ulong_int dimensionality; idl_byte base_type; IDL_bound_pair_t **p_range_list; IDL_msp_t IDL_msp; #endif { IDL_bound_pair_t *range_list; unsigned32 i; idl_ulong_int A,B; if (base_type == IDL_DT_STRING) dimensionality--; if (*p_range_list == NULL) { range_list = (IDL_bound_pair_t *)rpc_ss_mem_alloc (&IDL_msp->IDL_mem_handle, dimensionality * sizeof(IDL_bound_pair_t)); *p_range_list = range_list; } else range_list = *p_range_list; for (i=0; i Z_values[i]) { /* Bogus data stream with A,B values outside of Z bound value */ DCETHREAD_RAISE(rpc_x_invalid_bound); } } } for (i=0; (unsigned32)iIDL_type_vec + element_defn_index, (rpc_void_p_t)((idl_byte *)copy_addr + element_count * element_size), NULL, NULL, IDL_msp); } return; } } if ( (base_type == IDL_DT_FIXED_STRUCT) || (base_type == IDL_DT_ENC_UNION) || (base_type == IDL_DT_TRANSMIT_AS) || (base_type == IDL_DT_REPRESENT_AS) ) { /* Discard any of DT_MODIFIED, type, modifier, properties which may be present, and any filler bytes */ defn_vec_ptr += 4; IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr ); } if (dimensionality > IDL_NORMAL_DIMS) { control_data = (IDL_varying_control_t *)rpc_ss_mem_alloc( &IDL_msp->IDL_mem_handle, dimensionality * sizeof(IDL_varying_control_t)); } else control_data = normal_control_data; control_data[dimensionality-1].subslice_size = element_size; control_data[dimensionality-1].index_value = range_list[dimensionality-1].lower; for (i=dimensionality-2; i>=0; i--) { control_data[i].index_value = range_list[i].lower; control_data[i].subslice_size = control_data[i+1].subslice_size * Z_values[i+1]; } do { inner_slice_address = (idl_byte *)array_addr; for (i=0; (unsigned32)i= 0) { control_data[dim].index_value++; if (control_data[dim].index_value < (unsigned32)range_list[dim].upper) break; control_data[dim].index_value = range_list[dim].lower; dim--; } } while (dim >= 0); if (dimensionality > IDL_NORMAL_DIMS) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)control_data); } /******************************************************************************/ /* */ /* Unmarshall the Z values for a conformant or open array */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_Z_values #ifdef IDL_PROTOTYPES ( /* [in] */ idl_ulong_int dimensionality, /* [out] */ idl_ulong_int **p_Z_values, IDL_msp_t IDL_msp ) #else ( dimensionality, p_Z_values, IDL_msp ) idl_ulong_int dimensionality; idl_ulong_int **p_Z_values; IDL_msp_t IDL_msp; #endif { idl_ulong_int *Z_values; unsigned32 i; if (*p_Z_values == NULL) { Z_values = (idl_ulong_int *)rpc_ss_mem_alloc(&IDL_msp->IDL_mem_handle, dimensionality * sizeof(idl_ulong_int)); *p_Z_values = Z_values; } else Z_values = *p_Z_values; for (i=0; iIDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP) rpc_ss_fixed_bounds_from_vector(array_dims, array_defn_ptr, &bounds_list, IDL_msp); else bounds_list = (IDL_bound_pair_t *)array_defn_ptr; if (array_dims > IDL_NORMAL_DIMS) { Z_values = NULL; range_list = NULL; } else { Z_values = normal_Z_values; range_list = normal_range_list; } rpc_ss_Z_values_from_bounds( bounds_list, array_dims, &Z_values, IDL_msp ); array_defn_ptr += array_dims * IDL_FIXED_BOUND_PAIR_WIDTH; rpc_ss_ndr_unmar_range_list( array_dims, array_defn_ptr[array_dims * IDL_DATA_LIMIT_PAIR_WIDTH], &range_list, IDL_msp ); /* Check correlation and advance it to point at base type info */ rpc_ss_ndr_unmar_check_range_correlation( &array_defn_ptr, param_addr, NULL, NULL, array_dims, bounds_list, range_list, IDL_msp ); if ( type_has_pointers && (IDL_msp->IDL_side == IDL_server_side_k) ) { rpc_ss_init_new_array_ptrs( array_dims, Z_values, array_defn_ptr, param_addr, IDL_msp ); } rpc_ss_ndr_u_var_or_open_arr( array_dims, Z_values, array_defn_ptr, param_addr, range_list, flags, IDL_msp ); if (type_has_pointers) { /* By design array_defn_ptr is now at (0 mod 4) */ rpc_ss_ndr_u_v_or_o_arr_ptees( array_dims, Z_values, array_defn_ptr, param_addr, range_list, IDL_msp ); } if (array_dims > IDL_NORMAL_DIMS) { rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)range_list); rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values); } if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list); } /******************************************************************************/ /* */ /* Allocate an [out]-only conformant/open array */ /* */ /******************************************************************************/ static void rpc_ss_alloc_out_conf_array #ifdef IDL_PROTOTYPES ( /* [in,out] */ idl_byte **p_type_vec_ptr, /* Pointer to type vec pointer, which this routine updates */ /* [out] */ rpc_void_p_t *p_array_addr, /* Where to return address of allocated array */ /* [in,out] */ idl_ulong_int *p_num_conf_char_arrays ATTRIBUTE_UNUSED, /* Number of conformant char arrays */ IDL_msp_t IDL_msp ) #else ( p_type_vec_ptr, p_array_addr, p_num_conf_char_arrays, IDL_msp ) idl_byte **p_type_vec_ptr; rpc_void_p_t *p_array_addr; idl_ulong_int *p_num_conf_char_arrays; IDL_msp_t IDL_msp; #endif { idl_byte *type_vec_ptr = *p_type_vec_ptr; IDL_bound_pair_t *bounds_list; IDL_bound_pair_t normal_bounds_list[IDL_NORMAL_DIMS]; idl_byte array_type; /* DT_CONF_ARRAY or DT_OPEN_ARRAY */ idl_boolean type_has_pointers; idl_ulong_int array_defn_index; idl_byte *array_defn_ptr; idl_ulong_int dimensionality; idl_ulong_int *Z_values; idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS]; idl_boolean is_string; array_type = *type_vec_ptr; type_vec_ptr++; is_string = (array_type == IDL_DT_STRING); if ( is_string || (array_type == IDL_DT_V1_ARRAY) ) { /* Get array type following qualifier */ array_type = *type_vec_ptr; type_vec_ptr++; } /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Discard full array definition */ IDL_GET_LONG_FROM_VECTOR(array_defn_index,type_vec_ptr); array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index; dimensionality = (idl_ulong_int)*array_defn_ptr; array_defn_ptr++; if (dimensionality > IDL_NORMAL_DIMS) { bounds_list = NULL; Z_values = NULL; } else { bounds_list = normal_bounds_list; Z_values = normal_Z_values; } rpc_ss_build_bounds_list( &array_defn_ptr, NULL, NULL, NULL, dimensionality, &bounds_list, IDL_msp ); rpc_ss_Z_values_from_bounds( bounds_list, dimensionality, &Z_values, IDL_msp ); if (array_type == IDL_DT_OPEN_ARRAY) { /* Ignore the "varying" information */ array_defn_ptr += dimensionality * IDL_DATA_LIMIT_PAIR_WIDTH; } rpc_ss_ndr_alloc_storage( 0, dimensionality, Z_values, array_defn_ptr, p_array_addr, IDL_msp ); if (type_has_pointers) { rpc_ss_init_new_array_ptrs( dimensionality, Z_values, array_defn_ptr, *p_array_addr, IDL_msp ); } if (dimensionality > IDL_NORMAL_DIMS) { rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values); rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list); } *p_type_vec_ptr = type_vec_ptr; } /******************************************************************************/ /* */ /* Control for unmarshalling */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_interp #ifdef IDL_PROTOTYPES ( idl_ulong_int IDL_parameter_count, /* [in] -- Number of parameters to */ /* marshall in this call to the */ /* interpreter */ idl_ulong_int IDL_type_index, /* [in] -- Offset into the type vector */ /* for the description of the type to be */ /* marshalled */ rpc_void_p_t IDL_param_vector[], /* [in,out] -- The addresses of each of */ /* the the parameters thus it's size is */ /* the number of parameters in the */ /* signature of the operation */ IDL_msp_t IDL_msp /* [in,out] -- Pointer to marshalling state */ ) #else ( IDL_parameter_count, IDL_type_index, IDL_param_vector, IDL_msp) idl_ulong_int IDL_parameter_count; idl_ulong_int IDL_type_index; rpc_void_p_t IDL_param_vector[]; IDL_msp_t IDL_msp; #endif { idl_byte *type_vec_ptr; idl_byte type_byte; idl_ulong_int param_index; rpc_void_p_t param_addr; rpc_void_p_t *p_param_addr; idl_ulong_int defn_index; idl_boolean type_has_pointers; idl_boolean is_string = idl_false; idl_byte *struct_defn_ptr; idl_ulong_int offset_index; #if 0 idl_ulong_int rtn_index, iid_index; #endif idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */ idl_ulong_int array_defn_index; idl_byte *array_defn_ptr; idl_ulong_int conf_dims; /* Number of dimensions of conformance info */ idl_ulong_int *Z_values; idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS]; IDL_bound_pair_t *range_list; IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS]; IDL_bound_pair_t *bounds_list; IDL_bound_pair_t range_bounds; IDL_bound_pair_t *correl_bounds_list; IDL_bound_pair_t normal_correl_bounds_list[IDL_NORMAL_DIMS]; idl_ulong_int array_dims; /* Number of dimensions of array */ idl_ulong_int unique_flag; /* Wire form of [unique] pointer */ idl_byte *pointee_defn_ptr; IDL_pointee_desc_t pointee_desc; /* Description of pointee */ idl_ulong_int switch_value; /* Discriminant of non-encapsulated union */ intptr_t node_number = 0; idl_ushort_int v1_size; idl_ulong_int pseudo_Z_value; /* v1 conformant size */ idl_ulong_int num_conf_char_arrays; /* Number of conformant char arrays */ idl_byte **conf_char_array_list = NULL; /* List of pointers to type vec entries for conformant character arrays. Note that this list is only allocated if the language is FORTRAN. In this case it is written to for all parameters, but the list pointer is only advanced for conformant character arrays */ IDL_cs_shadow_elt_t *param_cs_shadow = NULL; /* cs-shadow for the parameter list */ idl_ulong_int param_shadow_length; /* Length of the cs-shadow for parameter list */ IDL_cs_shadow_elt_t *struct_cs_shadow; /* cs-shadow for the conformant structure */ idl_ulong_int struct_shadow_length; /* Length of the cs-shadow for a conformant structure */ IDL_INIT_RANGE( range_bounds ); if (IDL_msp->IDL_pickling_handle == NULL) { /* If pickling these variables are already set up */ IDL_msp->IDL_mp = (idl_byte *)IDL_msp->IDL_elt_p->data_addr; IDL_msp->IDL_left_in_buff = IDL_msp->IDL_elt_p->data_len; } num_conf_char_arrays = 0; if ((IDL_msp->IDL_language != IDL_lang_c_k) && (IDL_parameter_count != 0)) { conf_char_array_list = (idl_byte **)rpc_ss_mem_alloc( &IDL_msp->IDL_mem_handle, IDL_parameter_count * sizeof(idl_byte *)); } /* Loop over parameters */ type_vec_ptr = (IDL_msp->IDL_type_vec) + IDL_type_index; for ( ; IDL_parameter_count > 0; IDL_parameter_count -- ) { if (IDL_msp->IDL_language != IDL_lang_c_k) conf_char_array_list[num_conf_char_arrays] = type_vec_ptr; IDL_GET_LONG_FROM_VECTOR(param_index,type_vec_ptr); param_addr = IDL_param_vector[param_index]; do { type_byte = *type_vec_ptr; type_vec_ptr++; switch(type_byte) { case IDL_DT_BYTE: IDL_UNMAR_BYTE( param_addr ); IDL_CHECK_RANGE_BYTE( range_bounds, param_addr ); break; case IDL_DT_CHAR: IDL_UNMAR_CHAR( param_addr ); IDL_CHECK_RANGE_CHAR( range_bounds, param_addr ); break; case IDL_DT_BOOLEAN: IDL_UNMAR_BOOLEAN( param_addr ); IDL_CHECK_RANGE_BOOLEAN( range_bounds, param_addr ); break; case IDL_DT_DOUBLE: IDL_UNMAR_DOUBLE( param_addr ); IDL_CHECK_RANGE_DOUBLE( range_bounds, param_addr ); break; case IDL_DT_ENUM: IDL_UNMAR_ENUM( param_addr ); break; case IDL_DT_FLOAT: IDL_UNMAR_FLOAT( param_addr ); IDL_CHECK_RANGE_FLOAT( range_bounds, param_addr ); break; case IDL_DT_SMALL: IDL_UNMAR_SMALL( param_addr ); IDL_CHECK_RANGE_SMALL( range_bounds, param_addr ); break; case IDL_DT_SHORT: IDL_UNMAR_SHORT( param_addr ); IDL_CHECK_RANGE_SHORT( range_bounds, param_addr ); break; case IDL_DT_LONG: IDL_UNMAR_LONG( param_addr ); IDL_CHECK_RANGE_LONG( range_bounds, param_addr ); break; case IDL_DT_HYPER: IDL_UNMAR_HYPER( param_addr ); break; case IDL_DT_USMALL: IDL_UNMAR_USMALL( param_addr ); IDL_CHECK_RANGE_USMALL( range_bounds, param_addr ); break; case IDL_DT_USHORT: IDL_UNMAR_USHORT( param_addr ); IDL_CHECK_RANGE_USHORT( range_bounds, param_addr ); break; case IDL_DT_ULONG: IDL_UNMAR_ULONG( param_addr ); IDL_CHECK_RANGE_ULONG( range_bounds, param_addr ); break; case IDL_DT_UHYPER: IDL_UNMAR_UHYPER( param_addr ); break; case IDL_DT_V1_ENUM: IDL_UNMAR_V1_ENUM( param_addr ); break; case IDL_DT_ERROR_STATUS: IDL_UNMAR_ERROR_STATUS( param_addr ); break; case IDL_DT_FIXED_STRUCT: /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); if ( type_has_pointers && (IDL_msp->IDL_side == IDL_server_side_k) ) { rpc_ss_init_new_struct_ptrs( type_byte, IDL_msp->IDL_type_vec+defn_index, param_addr, NULL, IDL_msp ); } rpc_ss_ndr_unmar_struct(type_byte, IDL_msp->IDL_type_vec+defn_index, param_addr, NULL, NULL, IDL_msp); if (type_has_pointers) { rpc_ss_ndr_u_struct_pointees(type_byte, defn_index, param_addr, Z_values, IDL_msp); } break; case IDL_DT_CONF_STRUCT: case IDL_DT_V1_CONF_STRUCT: /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr); struct_defn_ptr = IDL_msp->IDL_type_vec + defn_index; IDL_GET_LONG_FROM_VECTOR(offset_index,struct_defn_ptr); struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index; IDL_GET_LONG_FROM_VECTOR(array_defn_index,struct_defn_ptr); array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index; if (*struct_defn_ptr == IDL_DT_CS_SHADOW) { struct_defn_ptr++; IDL_GET_LONG_FROM_VECTOR(struct_shadow_length, struct_defn_ptr); struct_cs_shadow = (IDL_cs_shadow_elt_t *) rpc_ss_mem_alloc (&IDL_msp->IDL_mem_handle, struct_shadow_length * sizeof(IDL_cs_shadow_elt_t)); } else struct_cs_shadow = NULL; conf_dims = (idl_ulong_int)*array_defn_ptr; array_defn_ptr++; if (conf_dims > IDL_NORMAL_DIMS) Z_values = NULL; else Z_values = normal_Z_values; if (type_byte == IDL_DT_V1_CONF_STRUCT) { IDL_UNMAR_CUSHORT( &v1_size ); *Z_values = (idl_ulong_int)v1_size; } else rpc_ss_ndr_unmar_Z_values( conf_dims, &Z_values, IDL_msp ); /* Skip over the bounds in the array defn to get to the base type */ IDL_ADV_DEFN_PTR_OVER_BOUNDS( array_defn_ptr, conf_dims ); if (*array_defn_ptr == IDL_DT_CS_TYPE) { rpc_ss_ndr_u_conf_cs_struct_hdr( IDL_msp->IDL_type_vec + defn_index, array_defn_ptr - IDL_CONF_BOUND_PAIR_WIDTH, Z_values, *struct_offset_vec_ptr, type_has_pointers, struct_shadow_length - 1, IDL_msp->IDL_side == IDL_server_side_k, struct_cs_shadow, &IDL_param_vector[param_index], IDL_msp); } else { if (IDL_msp->IDL_side == IDL_server_side_k) { if (type_byte == IDL_DT_V1_CONF_STRUCT) rpc_ss_ndr_alloc_storage(*struct_offset_vec_ptr, 1, Z_values, array_defn_ptr, &IDL_param_vector[param_index], IDL_msp); else rpc_ss_ndr_alloc_storage(*struct_offset_vec_ptr, conf_dims, Z_values, array_defn_ptr, &IDL_param_vector[param_index], IDL_msp); if (type_has_pointers) { rpc_ss_init_new_struct_ptrs( type_byte, IDL_msp->IDL_type_vec+defn_index, IDL_param_vector[param_index], Z_values, IDL_msp); } } } rpc_ss_ndr_unmar_struct(type_byte, IDL_msp->IDL_type_vec+defn_index, IDL_param_vector[param_index], Z_values, struct_cs_shadow, IDL_msp); if (type_has_pointers) { rpc_ss_ndr_u_struct_pointees(type_byte, defn_index, IDL_param_vector[param_index], Z_values, IDL_msp); } if (conf_dims > IDL_NORMAL_DIMS) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values); break; case IDL_DT_FIXED_ARRAY: /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Discard full array definition */ IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); if ( type_has_pointers && (IDL_msp->IDL_side == IDL_server_side_k) ) { array_defn_ptr = IDL_msp->IDL_type_vec + defn_index; array_dims = (idl_ulong_int)*array_defn_ptr; array_defn_ptr++; /* By design array_defn_ptr is now at (0 mod 4) */ if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP) rpc_ss_fixed_bounds_from_vector(array_dims, array_defn_ptr, &bounds_list, IDL_msp); else bounds_list = (IDL_bound_pair_t *)array_defn_ptr; /* Advance it to point at base type info */ array_defn_ptr += array_dims * IDL_FIXED_BOUND_PAIR_WIDTH; if (array_dims > IDL_NORMAL_DIMS) Z_values = NULL; else Z_values = normal_Z_values; rpc_ss_Z_values_from_bounds( bounds_list, array_dims, &Z_values, IDL_msp ); rpc_ss_init_new_array_ptrs( array_dims, Z_values, array_defn_ptr, param_addr, IDL_msp ); if (array_dims > IDL_NORMAL_DIMS) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values); if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list); } rpc_ss_ndr_unmar_fixed_arr(defn_index, param_addr, IDL_M_IS_PARAM, IDL_msp); if (type_has_pointers) { rpc_ss_ndr_u_fixed_arr_ptees(defn_index, param_addr, IDL_msp); } break; case IDL_DT_VARYING_ARRAY: /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Discard full array definition */ IDL_GET_LONG_FROM_VECTOR(array_defn_index, type_vec_ptr); array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index; rpc_ss_ndr_unmar_varying_arr( array_defn_ptr, type_has_pointers, param_addr, IDL_M_IS_PARAM | (is_string ? IDL_M_IS_STRING : 0), IDL_msp ); is_string = idl_false; break; case IDL_DT_CONF_ARRAY: /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Discard full array definition */ IDL_GET_LONG_FROM_VECTOR(array_defn_index,type_vec_ptr); array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index; conf_dims = (idl_ulong_int)*array_defn_ptr; array_defn_ptr++; if (conf_dims > IDL_NORMAL_DIMS) Z_values = NULL; else Z_values = normal_Z_values; rpc_ss_ndr_unmar_Z_values( conf_dims, &Z_values, IDL_msp ); rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr, &IDL_param_vector[param_index], NULL, NULL, conf_dims, Z_values, NULL, IDL_msp ); if (IDL_msp->IDL_side == IDL_server_side_k) { p_param_addr = &IDL_param_vector[param_index]; rpc_ss_ndr_alloc_storage( 0, conf_dims, Z_values, array_defn_ptr, p_param_addr, IDL_msp ); if (type_has_pointers) { rpc_ss_init_new_array_ptrs( conf_dims, Z_values, array_defn_ptr, IDL_param_vector[param_index], IDL_msp ); } } rpc_ss_ndr_u_fix_or_conf_arr( conf_dims, Z_values, array_defn_ptr, IDL_param_vector[param_index], IDL_M_IS_PARAM | IDL_M_CONF_ARRAY, IDL_msp ); if (type_has_pointers) { rpc_ss_ndr_u_f_or_c_arr_ptees( conf_dims, Z_values, array_defn_ptr, IDL_param_vector[param_index], IDL_msp ); } if (conf_dims > IDL_NORMAL_DIMS) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values); break; case IDL_DT_OPEN_ARRAY: /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Discard full array definition */ IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); array_defn_ptr = IDL_msp->IDL_type_vec + defn_index; conf_dims = (idl_ulong_int)*array_defn_ptr; array_defn_ptr++; if (conf_dims > IDL_NORMAL_DIMS) { Z_values = NULL; correl_bounds_list = NULL; range_list = NULL; } else { range_list = normal_range_list; Z_values = normal_Z_values; correl_bounds_list = normal_correl_bounds_list; } rpc_ss_ndr_unmar_Z_values( conf_dims, &Z_values, IDL_msp ); /* Check correlation and advance array_defn_ptr over data limit info */ rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr, &IDL_param_vector[param_index], NULL, NULL, conf_dims, Z_values, &correl_bounds_list, IDL_msp ); rpc_ss_ndr_unmar_range_list( conf_dims, array_defn_ptr[conf_dims * IDL_DATA_LIMIT_PAIR_WIDTH], &range_list, IDL_msp ); rpc_ss_ndr_unmar_check_range_correlation( &array_defn_ptr, &IDL_param_vector[param_index], NULL, NULL, conf_dims, correl_bounds_list, range_list, IDL_msp ); if (IDL_msp->IDL_side == IDL_server_side_k) { p_param_addr = &IDL_param_vector[param_index]; rpc_ss_ndr_alloc_storage( 0, conf_dims, Z_values, array_defn_ptr, p_param_addr, IDL_msp ); if (type_has_pointers) { rpc_ss_init_new_array_ptrs( conf_dims, Z_values, array_defn_ptr, IDL_param_vector[param_index], IDL_msp ); } } rpc_ss_ndr_u_var_or_open_arr( conf_dims, Z_values, array_defn_ptr, IDL_param_vector[param_index], range_list, IDL_M_CONF_ARRAY | IDL_M_IS_PARAM | (is_string ? IDL_M_IS_STRING : 0), IDL_msp ); if (type_has_pointers) { rpc_ss_ndr_u_v_or_o_arr_ptees( conf_dims, Z_values, array_defn_ptr, IDL_param_vector[param_index], range_list, IDL_msp ); } if (conf_dims > IDL_NORMAL_DIMS) { rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values); rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)correl_bounds_list); rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)range_list); } is_string = idl_false; break; case IDL_DT_ENC_UNION: /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); rpc_ss_ndr_u_enc_union_or_ptees( param_addr, defn_index, idl_false, IDL_msp); if (type_has_pointers) { rpc_ss_ndr_u_enc_union_or_ptees( param_addr, defn_index, idl_true, IDL_msp); } break; case IDL_DT_N_E_UNION: /* Properties byte */ type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS); type_vec_ptr++; IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Discard switch index */ IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); rpc_ss_ndr_unmar_n_e_union( param_addr, defn_index, &switch_value, IDL_msp); if (type_has_pointers) { rpc_ss_ndr_u_n_e_union_ptees( param_addr, switch_value, 0, defn_index, NULL, NULL, IDL_msp); } break; case IDL_DT_PASSED_BY_REF: break; case IDL_DT_FULL_PTR: { idl_ulong_int _node; type_vec_ptr++; /* Properties byte */ IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); /* Unmarshall the node number */ IDL_UNMAR_ULONG( &_node ); node_number = (intptr_t) _node; *(rpc_void_p_t *)(IDL_param_vector[param_index]) = (rpc_void_p_t)node_number; if (node_number != 0) { pointee_defn_ptr = IDL_msp->IDL_type_vec+defn_index; pointee_desc.dimensionality = 0; pointee_desc.struct_addr = NULL; pointee_desc.struct_offset_vec_ptr = NULL; rpc_ss_ndr_unmar_pointee_desc( type_byte, pointee_defn_ptr, &pointee_desc, IDL_param_vector[param_index], IDL_msp ); rpc_ss_ndr_unmar_pointee( type_byte, pointee_defn_ptr, &pointee_desc, IDL_param_vector[param_index], IDL_msp ); rpc_ss_ndr_u_rlse_pointee_desc(&pointee_desc, IDL_msp); } break; } case IDL_DT_UNIQUE_PTR: type_vec_ptr++; /* Properties byte */ IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); IDL_UNMAR_ULONG( &unique_flag ); if (unique_flag == 0) { *(rpc_void_p_t *)(IDL_param_vector[param_index]) = NULL; } else { pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index; pointee_desc.dimensionality = 0; pointee_desc.struct_addr = NULL; pointee_desc.struct_offset_vec_ptr = NULL; rpc_ss_ndr_unmar_pointee_desc( type_byte, pointee_defn_ptr, &pointee_desc, IDL_param_vector[param_index], IDL_msp ); if ((IDL_msp->IDL_side == IDL_server_side_k) || (*(rpc_void_p_t *)(IDL_param_vector[param_index]) == NULL)) { *(rpc_void_p_t *)(IDL_param_vector[param_index]) = IDL_NEW_NODE; } rpc_ss_ndr_unmar_pointee( type_byte, pointee_defn_ptr, &pointee_desc, IDL_param_vector[param_index], IDL_msp ); rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp ); } break; case IDL_DT_REF_PTR: type_vec_ptr++; /* Properties byte */ IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); pointee_defn_ptr = IDL_msp->IDL_type_vec+defn_index; if (IDL_msp->IDL_side == IDL_server_side_k) { rpc_ss_alloc_pointer_target(pointee_defn_ptr, IDL_param_vector[param_index], IDL_msp ); } pointee_desc.dimensionality = 0; pointee_desc.struct_addr = NULL; pointee_desc.struct_offset_vec_ptr = NULL; rpc_ss_ndr_unmar_pointee_desc( type_byte, pointee_defn_ptr, &pointee_desc, IDL_param_vector[param_index], IDL_msp ); rpc_ss_ndr_unmar_pointee( type_byte, pointee_defn_ptr, &pointee_desc, IDL_param_vector[param_index], IDL_msp ); rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp ); break; case IDL_DT_STRING: /* Varying/open array code will do the right thing */ is_string = idl_true; break; case IDL_DT_TRANSMIT_AS: case IDL_DT_REPRESENT_AS: type_vec_ptr++; /* Properties byte */ IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr); rpc_ss_ndr_unmar_xmit_as(defn_index, IDL_param_vector[param_index], NULL, IDL_msp ); break; #if 0 case IDL_DT_INTERFACE: type_vec_ptr++; /* Properties byte */ IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr); rpc_ss_ndr_unmar_interface(defn_index, IDL_param_vector[param_index], NULL, IDL_msp ); break; case IDL_DT_DYN_INTERFACE: type_vec_ptr++; /* Properties byte */ IDL_GET_LONG_FROM_VECTOR(rtn_index, type_vec_ptr); IDL_GET_LONG_FROM_VECTOR(iid_index, type_vec_ptr); rpc_ss_ndr_unmar_dyn_interface(rtn_index, IDL_param_vector[param_index], ((uuid_t *) IDL_param_vector[iid_index]), NULL, IDL_msp ); break; #endif case IDL_DT_ALLOCATE: /* Indicates an [out]-only conformant or open array must be allocated. Should only appear on server side */ rpc_ss_alloc_out_conf_array( &type_vec_ptr, &IDL_param_vector[param_index], &num_conf_char_arrays, IDL_msp ); break; case IDL_DT_ALLOCATE_REF: /* Indicates that the pointees of [ref] pointers in an [out] only parameter must be allocated. Should only appear on server side */ rpc_ss_init_out_ref_ptrs( &type_vec_ptr, param_addr, IDL_msp ); break; case IDL_DT_PIPE: if (IDL_msp->IDL_side == IDL_server_side_k) { /* Rest of unmarshalling is done by manager calls */ return; } else { type_vec_ptr++; /* Properties byte */ IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); rpc_ss_ndr_unmar_pipe(defn_index, param_addr, IDL_msp); } break; case IDL_DT_IN_CONTEXT: case IDL_DT_IN_OUT_CONTEXT: case IDL_DT_OUT_CONTEXT: rpc_ss_ndr_unmar_context(type_byte, param_addr, IDL_msp); break; case IDL_DT_V1_ARRAY: type_byte = *type_vec_ptr; /* DT_VARYING or DT_OPEN */ type_vec_ptr += 2; /* Skip over properties byte */ IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Discard full array definition */ IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr); array_defn_ptr = IDL_msp->IDL_type_vec + defn_index; array_dims = (idl_ulong_int)*array_defn_ptr; array_defn_ptr++; if (type_byte == IDL_DT_OPEN_ARRAY) { IDL_ADV_DEFN_PTR_OVER_BOUNDS( array_defn_ptr, array_dims ); /* Advance array_defn_ptr over data limit info */ array_defn_ptr += array_dims * IDL_DATA_LIMIT_PAIR_WIDTH; IDL_UNMAR_CUSHORT( &v1_size ); if (IDL_msp->IDL_side == IDL_server_side_k) { pseudo_Z_value = (idl_ulong_int)v1_size; rpc_ss_ndr_alloc_storage( 0, 1, &pseudo_Z_value, array_defn_ptr, &IDL_param_vector[param_index], IDL_msp ); } } else /* IDL_DT_VARYING_ARRAY */ { array_defn_ptr += array_dims * (IDL_FIXED_BOUND_PAIR_WIDTH + IDL_DATA_LIMIT_PAIR_WIDTH); } rpc_ss_ndr_u_v1_varying_arr(IDL_param_vector[param_index], array_defn_ptr, IDL_M_IS_PARAM, IDL_msp ); break; case IDL_DT_V1_STRING: type_vec_ptr += 2; /* DT_VARYING_ARRAY and properties */ IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Full array defn */ IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); /* Flattened array defn */ rpc_ss_ndr_unmar_v1_string(param_addr, IDL_M_IS_PARAM, IDL_msp); break; case IDL_DT_FREE_REP: /* Just needs skipping over */ IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr); break; case IDL_DT_DELETED_NODES: rpc_ss_ndr_unmar_deletes(IDL_msp); break; case IDL_DT_CS_SHADOW: IDL_GET_LONG_FROM_VECTOR(param_shadow_length, type_vec_ptr); param_cs_shadow = (IDL_cs_shadow_elt_t *) rpc_ss_mem_alloc (&IDL_msp->IDL_mem_handle, param_shadow_length * sizeof(IDL_cs_shadow_elt_t)); break; case IDL_DT_CS_ARRAY: if (*type_vec_ptr == IDL_DT_ALLOCATE) { rpc_ss_alloc_out_cs_conf_array(param_cs_shadow, &type_vec_ptr, &IDL_param_vector[param_index], IDL_msp); } else { rpc_ss_ndr_u_cs_array_param(&type_vec_ptr, param_cs_shadow, param_index, IDL_msp); } break; case IDL_DT_CS_ATTRIBUTE: /* Unmarshall the parameter normally. It will get overwritten later */ break; case IDL_DT_CS_TYPE: type_vec_ptr++; /* Properties byte */ IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr); rpc_ss_ndr_unmar_cs_char(param_addr, defn_index, IDL_msp); break; case IDL_DT_CS_RLSE_SHADOW: rpc_ss_ndr_u_param_cs_shadow( IDL_type_index, param_cs_shadow, IDL_msp); break; case IDL_DT_RANGE: IDL_GET_RANGE_FROM_VECTOR(range_bounds, type_vec_ptr); break; case IDL_DT_EOL: break; default: #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_interp:unrecognized type %d\n", type_byte); exit(0); #endif DCETHREAD_RAISE(rpc_x_coding_error); } } while (type_byte != IDL_DT_EOL); } if ((IDL_msp->IDL_language != IDL_lang_c_k) && (IDL_parameter_count != 0)) { rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)conf_char_array_list); } if (IDL_msp->IDL_pickling_handle == NULL) { if (IDL_msp->IDL_elt_p->buff_dealloc && IDL_msp->IDL_elt_p->data_len != 0) (*(IDL_msp->IDL_elt_p->buff_dealloc)) (IDL_msp->IDL_elt_p->buff_addr); IDL_msp->IDL_elt_p = NULL; } else { /* For pickling, buffer was rounded out to a multiple of 8 bytes */ IDL_UNMAR_ALIGN_MP(IDL_msp, 8); } } /******************************************************************************/ /* */ /* Create a bitmap indicating which dimensions are determined from */ /* parameters or fields that occur before the struct or array definition */ /* itself. */ /* */ /******************************************************************************/ static void rpc_ss_ndr_unmar_cf_early #ifdef IDL_PROTOTYPES ( /* [in] */ idl_byte **p_defn_vec_ptr, /* if early, not modified */ /* if late, points past bounds/limit info */ /* [in] */ idl_ulong_int dimensionality, /* dimensionality of array */ /* [out] */ idl_boolean **p_early_list, IDL_msp_t IDL_msp ) #else (p_defn_vec_ptr, dimensionality, p_early_list, IDL_msp) idl_byte **p_defn_vec_ptr; idl_ulong_int dimensionality; idl_boolean **p_early_list; IDL_msp_t IDL_msp; #endif { idl_ulong_int i; idl_byte *defn_vec_ptr = *p_defn_vec_ptr; idl_boolean *early_list; if (*p_early_list == NULL) { early_list = (idl_boolean *)rpc_ss_mem_alloc (&IDL_msp->IDL_mem_handle, dimensionality * sizeof(idl_boolean)); } else early_list = *p_early_list; for (i = 0; i < dimensionality; i++) { idl_byte kind; idl_ulong_int attribute_index = 0; idl_boolean early; kind = (*defn_vec_ptr & IDL_LIMIT_TYPE_MASK); early = !!(*defn_vec_ptr & IDL_CF_EARLY); defn_vec_ptr++; early_list[i] = idl_true; /* Get lower bound or limit */ if (kind == IDL_LIMIT_FIXED) { IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); } else { defn_vec_ptr++; IDL_GET_LONG_FROM_VECTOR(attribute_index, defn_vec_ptr); if (!early) { #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_cf_early: " "IDL_CF_EARLY not set for (lower) attribute %ld\n", attribute_index); #endif early_list[i] = idl_false; } } /* Get upper bound or limit */ kind = (*defn_vec_ptr & IDL_LIMIT_TYPE_MASK); early = !!(*defn_vec_ptr & IDL_CF_EARLY); defn_vec_ptr++; if (kind == IDL_LIMIT_FIXED) { IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); } else { if (kind == IDL_LIMIT_LENGTH_IS) defn_vec_ptr++; /* discard function code */ defn_vec_ptr++; IDL_GET_LONG_FROM_VECTOR(attribute_index, defn_vec_ptr); if (kind == IDL_LIMIT_LENGTH_IS && early) { #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_cf_early: " "IDL_CF_EARLY set for (size_is) attribute %ld\n", attribute_index); #endif early = false; early_list[i] = idl_false; } else if (kind != IDL_LIMIT_UPPER_CONF && !early) { #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_cf_early: " "IDL_CF_EARLY not set for (upper) attribute %ld\n", attribute_index); #endif early_list[i] = idl_false; } } } /* * If all dimensions are determined by fields or parameters that * occur later, then return NULL and advance the definition pointer. */ for (i = 0; i < dimensionality; i++) { if (early_list[i]) { *p_early_list = early_list; return; } } if (*p_early_list == NULL) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)early_list); *p_early_list = NULL; /* Advance past bounds/limits */ *p_defn_vec_ptr = defn_vec_ptr; } /******************************************************************************/ /* */ /* Perform bounds correlation checking; only works for early bindings */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_check_bounds_correlation #ifdef IDL_PROTOTYPES ( /* [in] */ idl_byte **p_defn_vec_ptr, /* [in] */ rpc_void_p_t array_addr, /* [in] */ rpc_void_p_t struct_addr, /* [in] */ idl_ulong_int *struct_offset_vec_ptr, /* [in] */ idl_ulong_int dimensionality, /* [in] */ idl_ulong_int *Z_values, /* [out] */ IDL_bound_pair_t **p_correl_bounds_list, IDL_msp_t IDL_msp ) #else (p_defn_vec_ptr, array_addr, struct_addr, struct_offset_vec_ptr, dimensionality, Z_values, p_correl_bounds_list IDL_ms) idl_byte **p_defn_vec_ptr; rpc_void_p_t array_addr; rpc_void_p_t struct_addr; idl_ulong_int *struct_offset_vec_ptr; idl_ulong_int dimensionality; idl_ulong_int *Z_values; IDL_bound_pair_t **p_correl_bounds_list; IDL_msp_t IDL_msp; #endif { IDL_bound_pair_t *correl_bounds_list; IDL_bound_pair_t normal_correl_bounds_list[IDL_NORMAL_DIMS]; idl_boolean *early_list; idl_boolean normal_early_list[IDL_NORMAL_DIMS]; idl_ulong_int i; idl_boolean correl_ok = idl_true; idl_boolean free_correl_bounds_list = idl_false; /* * If the correlated bounds are marshalled after the "NDR" bounds, * then correlation checking is only possible after unmarshalling. * This is not supported at present. To avoid attempting to read * uninitialized memory we simply return if the correlation is not * "early". * * Note: the following code assumes invariance between IDL_BOUND_ * and IDL_LIMIT_. If you change these constants this will break. */ if (dimensionality > IDL_NORMAL_DIMS) early_list = NULL; else early_list = normal_early_list; rpc_ss_ndr_unmar_cf_early(p_defn_vec_ptr, dimensionality, &early_list, IDL_msp); if (early_list == NULL) return; if (p_correl_bounds_list == NULL) { if (dimensionality > IDL_NORMAL_DIMS) { correl_bounds_list = NULL; free_correl_bounds_list = idl_true; } else { correl_bounds_list = normal_correl_bounds_list; } p_correl_bounds_list = &correl_bounds_list; } rpc_ss_build_bounds_list_2(p_defn_vec_ptr, array_addr, struct_addr, struct_offset_vec_ptr, dimensionality, early_list, p_correl_bounds_list, IDL_msp); for (i = 0; i < dimensionality; i++) { idl_ulong_int correl_Z_value; IDL_bound_pair_t *correl_bounds = &((*p_correl_bounds_list)[i]); if (early_list[i] == idl_false) continue; if (correl_bounds->upper >= correl_bounds->lower) correl_Z_value = correl_bounds->upper - correl_bounds->lower + 1; else correl_Z_value = 0; if (Z_values[i] != correl_Z_value) { #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_check_bounds_correlation: " "Z_value correlation mismatch (%ld != %ld)\n", correl_Z_value, Z_values[i]); #endif correl_ok = idl_false; break; } } if (free_correl_bounds_list) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)correl_bounds_list); if (dimensionality > IDL_NORMAL_DIMS) rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)early_list); if (correl_ok == idl_false) DCETHREAD_RAISE( rpc_x_invalid_bound ); } /******************************************************************************/ /* */ /* Perform limits correlation checking; only works for early bindings */ /* */ /******************************************************************************/ void rpc_ss_ndr_unmar_check_range_correlation #ifdef IDL_PROTOTYPES ( /* [in] */ idl_byte **p_defn_vec_ptr, /* [in] */ rpc_void_p_t array_addr, /* [in] */ rpc_void_p_t struct_addr, /* [in] */ idl_ulong_int *struct_offset_vec_ptr, /* [in] */ idl_ulong_int dimensionality, /* [in] */ IDL_bound_pair_t *bounds_list, /* [in] */ IDL_bound_pair_t *range_list, /* [in] */ IDL_msp_t IDL_msp ) #else (p_defn_vec_ptr, array_addr, struct_addr, struct_offset_vec_ptr, dimensionality, bounds_list, range_list, IDL_ms) idl_byte **p_defn_vec_ptr; rpc_void_p_t array_addr; rpc_void_p_t struct_addr; idl_ulong_int *struct_offset_vec_ptr; idl_ulong_int dimensionality; IDL_bound_pair_t *bounds_list; IDL_bound_pair_t *range_list; IDL_msp_t IDL_msp; #endif { IDL_bound_pair_t *correl_range_list; IDL_bound_pair_t normal_correl_range_list[IDL_NORMAL_DIMS]; idl_boolean *early_list; idl_boolean normal_early_list[IDL_NORMAL_DIMS]; idl_ulong_int i; idl_boolean add_null; idl_boolean correl_ok = idl_true; if (bounds_list == NULL) { #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_check_range_correlation: " "no bounds list provided\n"); #endif return; } /* * If the correlated bounds are marshalled after the "NDR" bounds, * then correlation checking is only possible after unmarshalling. * This is not supported at present. To avoid attempting to read * uninitialized memory we simply return if the correlation is not * "early". * * Note: the following code assumes invariance between IDL_BOUND_ * and IDL_LIMIT_. If you change these constants this will break. */ if (dimensionality > IDL_NORMAL_DIMS) early_list = NULL; else early_list = normal_early_list; rpc_ss_ndr_unmar_cf_early(p_defn_vec_ptr, dimensionality, &early_list, IDL_msp); if (early_list == NULL) return; if (dimensionality > IDL_NORMAL_DIMS) correl_range_list = NULL; else correl_range_list = normal_correl_range_list; rpc_ss_build_range_list_2(p_defn_vec_ptr, array_addr, struct_addr, struct_offset_vec_ptr, dimensionality, bounds_list, early_list, &correl_range_list, &add_null, IDL_msp); for (i = 0; i < dimensionality; i++) { IDL_bound_pair_t *range = &range_list[i]; IDL_bound_pair_t *correl_range = &correl_range_list[i]; if (early_list[i] == idl_false) continue; if (range->lower != correl_range->lower) { #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_check_range_correlation: " "lower correlation mismatch (%ld != %ld)\n", correl_range->lower, range->lower); #endif correl_ok = idl_false; break; } else if (range->upper != correl_range->upper) { #ifdef DEBUG_INTERP printf("rpc_ss_ndr_unmar_check_range_correlation: " "upper correlation mismatch (%ld != %ld)\n", correl_range->upper, range->upper); #endif correl_ok = idl_false; break; } } if (dimensionality > IDL_NORMAL_DIMS) { rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)correl_range_list); rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)early_list); } if (correl_ok == idl_false) DCETHREAD_RAISE( rpc_x_invalid_bound ); }