1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**
79**      ndrmi2.c
80**
81**  FACILITY:
82**
83**      Interface Definition Language (IDL) Compiler
84**
85**  ABSTRACT:
86**
87**      NDR marshalling interpreter modules for - pointers
88**
89*/
90#if HAVE_CONFIG_H
91#include <config.h>
92#endif
93
94#include <dce/idlddefs.h>
95#include <ndrmi.h>
96#include <lsysdep.h>
97
98static void rpc_ss_ndr_m_f_or_c_arr_ptees
99(
100    rpc_void_p_t array_addr,
101    idl_ulong_int dimensionality,
102    IDL_bound_pair_t *bounds_list,
103    idl_byte *defn_vec_ptr,
104    IDL_msp_t IDL_msp
105);
106
107static void rpc_ss_ndr_m_v_or_o_arr_ptees
108(
109    rpc_void_p_t array_addr,
110    idl_ulong_int *Z_values,
111    idl_ulong_int dimensionality,
112    IDL_bound_pair_t *range_list,
113    idl_byte *defn_vec_ptr,
114    IDL_msp_t IDL_msp
115);
116
117/******************************************************************************/
118/*                                                                            */
119/*  Marshall the target of a pointer                                          */
120/*  All params apart from IDL_msp are [in]                                    */
121/*                                                                            */
122/******************************************************************************/
123void rpc_ss_ndr_marsh_pointee
124(
125    idl_byte *defn_vec_ptr,         /* On entry points at type of pointee */
126    rpc_void_p_t pointee_addr,      /* address of pointee */
127    idl_boolean register_node,      /* TRUE => this is the pointee of a
128                                        deferred [ptr] pointer */
129    IDL_pointee_desc_t *p_pointee_desc, /* Data describing pointee
130                               - not used unless pointee is non-fixed array
131                                                or non-encapsulated union */
132    IDL_msp_t IDL_msp
133)
134{
135    long already_marshalled;
136    idl_byte pointee_type;
137    idl_ulong_int pointee_defn_index;   /* Offset of the pointee type
138                                         description in the definition vector */
139    idl_boolean type_has_pointers;
140    idl_ulong_int node_number;
141    idl_byte *array_defn_ptr;
142    idl_ulong_int switch_index;
143    IDL_pointee_desc_t pointee_desc;    /* Description of pointee */
144    IDL_bound_pair_t range_bounds;
145
146    if (register_node)
147    {
148        rpc_ss_register_node( IDL_msp->IDL_node_table, (byte_p_t)pointee_addr,
149                                idl_true, &already_marshalled );
150        if (already_marshalled)
151            return;
152    }
153
154    pointee_type = *defn_vec_ptr;
155    pointee_desc.dimensionality = 0;
156
157    if (pointee_type == IDL_DT_STRING)
158    {
159        /* Varying/open array code will do the right thing */
160        defn_vec_ptr++;
161        pointee_type = *defn_vec_ptr;
162    }
163
164    IDL_INIT_RANGE(range_bounds);
165    if (pointee_type == IDL_DT_RANGE)
166    {
167        IDL_GET_RANGE_FROM_VECTOR(range_bounds, defn_vec_ptr);
168        pointee_type = *defn_vec_ptr;
169    }
170
171    switch(pointee_type)
172    {
173        case IDL_DT_BOOLEAN:
174            IDL_CHECK_RANGE_BOOLEAN( range_bounds, pointee_addr );
175            IDL_MARSH_BOOLEAN( pointee_addr );
176            break;
177        case IDL_DT_BYTE:
178            IDL_CHECK_RANGE_BYTE( range_bounds, pointee_addr );
179            IDL_MARSH_BYTE( pointee_addr );
180            break;
181        case IDL_DT_CHAR:
182            IDL_CHECK_RANGE_CHAR( range_bounds, pointee_addr );
183            IDL_MARSH_CHAR( pointee_addr );
184            break;
185        case IDL_DT_SMALL:
186            IDL_CHECK_RANGE_SMALL( range_bounds, pointee_addr );
187            IDL_MARSH_SMALL( pointee_addr );
188            break;
189        case IDL_DT_USMALL:
190            IDL_CHECK_RANGE_USMALL( range_bounds, pointee_addr );
191            IDL_MARSH_USMALL( pointee_addr );
192            break;
193        case IDL_DT_ENUM:
194            IDL_MARSH_ENUM( pointee_addr );
195            break;
196        case IDL_DT_SHORT:
197            IDL_CHECK_RANGE_SHORT( range_bounds, pointee_addr );
198            IDL_MARSH_SHORT( pointee_addr );
199            break;
200        case IDL_DT_USHORT:
201            IDL_CHECK_RANGE_USHORT( range_bounds, pointee_addr );
202            IDL_MARSH_USHORT( pointee_addr );
203            break;
204        case IDL_DT_FLOAT:
205            IDL_CHECK_RANGE_FLOAT( range_bounds, pointee_addr );
206            IDL_MARSH_FLOAT( pointee_addr );
207            break;
208        case IDL_DT_LONG:
209            IDL_CHECK_RANGE_LONG( range_bounds, pointee_addr );
210            IDL_MARSH_LONG( pointee_addr );
211            break;
212        case IDL_DT_ULONG:
213            IDL_CHECK_RANGE_ULONG( range_bounds, pointee_addr );
214            IDL_MARSH_ULONG( pointee_addr );
215            break;
216        case IDL_DT_DOUBLE:
217            IDL_CHECK_RANGE_DOUBLE( range_bounds, pointee_addr );
218            IDL_MARSH_DOUBLE( pointee_addr );
219            break;
220        case IDL_DT_HYPER:
221            IDL_MARSH_HYPER( pointee_addr );
222            break;
223        case IDL_DT_UHYPER:
224            IDL_MARSH_UHYPER( pointee_addr );
225            break;
226        case IDL_DT_ERROR_STATUS:
227            IDL_MARSH_ERROR_STATUS( pointee_addr );
228            break;
229        case IDL_DT_CONF_STRUCT:
230        case IDL_DT_FIXED_STRUCT:
231            /* Properties byte */
232            defn_vec_ptr++;
233            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
234            defn_vec_ptr++;
235            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
236            rpc_ss_ndr_marsh_struct(pointee_type, pointee_defn_index,
237                                    pointee_addr, IDL_msp);
238            if (type_has_pointers)
239            {
240                rpc_ss_ndr_m_struct_pointees(pointee_type, pointee_defn_index,
241                                                pointee_addr, IDL_msp);
242            }
243            break;
244        case IDL_DT_FIXED_ARRAY:
245            /* Properties byte */
246            defn_vec_ptr++;
247            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
248            defn_vec_ptr++;
249            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
250                                             /* Discard full array definition */
251            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
252            rpc_ss_ndr_marsh_fixed_arr(pointee_defn_index,
253                                       pointee_addr, 0, IDL_msp);
254            if (type_has_pointers)
255            {
256                rpc_ss_ndr_m_dfc_arr_ptees(pointee_defn_index,
257                                          pointee_addr, NULL, NULL, 0, IDL_msp);
258            }
259            break;
260        case IDL_DT_VARYING_ARRAY:
261            defn_vec_ptr += 2;      /* Byte after properties byte */
262            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
263                                             /* Discard full array definition */
264            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
265            array_defn_ptr = IDL_msp->IDL_type_vec + pointee_defn_index;
266            /* Advance over dimensionality, bounds and data limit info */
267            array_defn_ptr += (1 + (p_pointee_desc->dimensionality
268                                  * (IDL_FIXED_BOUND_PAIR_WIDTH
269                                        + IDL_DATA_LIMIT_PAIR_WIDTH)));
270            rpc_ss_ndr_m_var_or_open_arr( pointee_addr,
271                                          p_pointee_desc->Z_values,
272                                          p_pointee_desc->dimensionality,
273                                          p_pointee_desc->range_list,
274                                          array_defn_ptr, 0, IDL_msp );
275            if (p_pointee_desc->base_type_has_pointers)
276            {
277               rpc_ss_ndr_m_v_or_o_arr_ptees( pointee_addr,
278                                             p_pointee_desc->Z_values,
279                                             p_pointee_desc->dimensionality,
280                                             p_pointee_desc->range_list,
281                                             array_defn_ptr, IDL_msp );
282            }
283            break;
284        case IDL_DT_CONF_ARRAY:
285            defn_vec_ptr += 2;      /* Byte after properties byte */
286            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
287                                             /* Discard full array definition */
288            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
289            array_defn_ptr = IDL_msp->IDL_type_vec + pointee_defn_index;
290            array_defn_ptr++;       /* Dimensionality byte */
291            IDL_ADV_DEFN_PTR_OVER_BOUNDS(array_defn_ptr,
292                                             p_pointee_desc->dimensionality);
293            rpc_ss_ndr_marsh_Z_values( p_pointee_desc->dimensionality,
294                                       p_pointee_desc->Z_values, IDL_msp );
295            rpc_ss_ndr_m_fix_or_conf_arr( pointee_addr,
296                                          p_pointee_desc->dimensionality,
297                                          p_pointee_desc->bounds_list,
298                                          array_defn_ptr, IDL_M_CONF_ARRAY,
299                                          IDL_msp );
300            if (p_pointee_desc->base_type_has_pointers)
301            {
302               rpc_ss_ndr_m_f_or_c_arr_ptees( pointee_addr,
303                                             p_pointee_desc->dimensionality,
304                                             p_pointee_desc->bounds_list,
305                                             array_defn_ptr, IDL_msp );
306            }
307            break;
308        case IDL_DT_OPEN_ARRAY:
309            defn_vec_ptr += 2;      /* Byte after properties byte */
310            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
311                                             /* Discard full array definition */
312            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
313            array_defn_ptr = IDL_msp->IDL_type_vec + pointee_defn_index;
314            array_defn_ptr++;       /* Dimensionality byte */
315            IDL_ADV_DEFN_PTR_OVER_BOUNDS(array_defn_ptr,
316                                             p_pointee_desc->dimensionality);
317            rpc_ss_ndr_marsh_Z_values( p_pointee_desc->dimensionality,
318                                       p_pointee_desc->Z_values, IDL_msp );
319            array_defn_ptr += p_pointee_desc->dimensionality
320                                                    * IDL_DATA_LIMIT_PAIR_WIDTH;
321            rpc_ss_ndr_m_var_or_open_arr( pointee_addr,
322                                          p_pointee_desc->Z_values,
323                                          p_pointee_desc->dimensionality,
324                                          p_pointee_desc->range_list,
325                                          array_defn_ptr, 0, IDL_msp );
326            if (p_pointee_desc->base_type_has_pointers)
327            {
328               rpc_ss_ndr_m_v_or_o_arr_ptees( pointee_addr,
329                                             p_pointee_desc->Z_values,
330                                             p_pointee_desc->dimensionality,
331                                             p_pointee_desc->range_list,
332                                             array_defn_ptr, IDL_msp );
333            }
334            break;
335        case IDL_DT_ENC_UNION:
336            /* Properties byte */
337            defn_vec_ptr++;
338            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
339            defn_vec_ptr++;
340            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
341            rpc_ss_ndr_m_enc_union_or_ptees(pointee_addr, pointee_defn_index,
342                                            idl_false, IDL_msp);
343            if (type_has_pointers)
344            {
345                rpc_ss_ndr_m_enc_union_or_ptees(pointee_addr,
346                                        pointee_defn_index, idl_true, IDL_msp);
347            }
348            break;
349        case IDL_DT_N_E_UNION:
350            /* Properties byte */
351            defn_vec_ptr++;
352            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
353            defn_vec_ptr++;
354            IDL_GET_LONG_FROM_VECTOR(switch_index,defn_vec_ptr);
355            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
356            rpc_ss_ndr_m_n_e_union_or_ptees(pointee_addr, switch_index,
357                                          pointee_defn_index,
358                                          p_pointee_desc->struct_addr,
359                                          p_pointee_desc->struct_offset_vec_ptr,
360                                          idl_false, IDL_msp);
361            if (type_has_pointers)
362            {
363                rpc_ss_ndr_m_n_e_union_or_ptees(pointee_addr, switch_index,
364                                          pointee_defn_index,
365                                          p_pointee_desc->struct_addr,
366                                          p_pointee_desc->struct_offset_vec_ptr,
367                                          idl_true, IDL_msp);
368            }
369            break;
370        case IDL_DT_FULL_PTR:
371            node_number = rpc_ss_register_node( IDL_msp->IDL_node_table,
372                          (byte_p_t)*(rpc_void_p_t *)pointee_addr, ndr_true,
373                          &already_marshalled );
374            IDL_MARSH_ULONG( &node_number );
375            if ((*(rpc_void_p_t *)pointee_addr != NULL) && !already_marshalled)
376            {
377                defn_vec_ptr++;
378                rpc_ss_pointee_desc_from_data( defn_vec_ptr,
379                                          *(rpc_void_p_t *)pointee_addr,
380                                          NULL, NULL, &pointee_desc, IDL_msp );
381                rpc_ss_ndr_marsh_pointee( defn_vec_ptr,
382                                          *(rpc_void_p_t *)pointee_addr,
383                                          idl_false, &pointee_desc, IDL_msp );
384            }
385            break;
386        case IDL_DT_UNIQUE_PTR:
387            /* Get a value of 0 if pointer is null, 1 otherwise */
388            node_number = ((byte_p_t)*(rpc_void_p_t *)pointee_addr != NULL);
389            IDL_MARSH_ULONG( &node_number );
390            if (*(rpc_void_p_t *)pointee_addr != NULL)
391            {
392                defn_vec_ptr++;
393                rpc_ss_pointee_desc_from_data( defn_vec_ptr,
394                                          *(rpc_void_p_t *)pointee_addr,
395                                          NULL, NULL, &pointee_desc, IDL_msp );
396                rpc_ss_ndr_marsh_pointee( defn_vec_ptr,
397                                          *(rpc_void_p_t *)pointee_addr,
398                                          idl_false, &pointee_desc, IDL_msp );
399            }
400            break;
401        case IDL_DT_REF_PTR:
402            /* For naked ref pointer, just marshall the pointee */
403            defn_vec_ptr++;
404            rpc_ss_pointee_desc_from_data( defn_vec_ptr,
405                                          *(rpc_void_p_t *)pointee_addr,
406                                          NULL, NULL, &pointee_desc, IDL_msp );
407            rpc_ss_ndr_marsh_pointee( defn_vec_ptr,
408                                          *(rpc_void_p_t *)pointee_addr,
409                                          idl_false, &pointee_desc, IDL_msp );
410            break;
411        case IDL_DT_TRANSMIT_AS:
412        case IDL_DT_REPRESENT_AS:
413            defn_vec_ptr += 2;      /* Byte after properties byte */
414            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
415            rpc_ss_ndr_marsh_xmit_as(pointee_defn_index, pointee_addr, IDL_msp);
416            break;
417#if 0
418        case IDL_DT_INTERFACE:
419            defn_vec_ptr += 2;      /* Byte after properties byte */
420            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
421            rpc_ss_ndr_marsh_interface(pointee_defn_index,pointee_addr,IDL_msp);
422            break;
423#endif
424        case IDL_DT_CS_TYPE:
425            defn_vec_ptr += 2;      /* Byte after properties byte */
426            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
427            rpc_ss_ndr_marsh_cs_char(pointee_addr, pointee_defn_index, IDL_msp);
428            break;
429        case IDL_DT_CS_ARRAY:
430            rpc_ss_ndr_m_fixed_cs_array(pointee_addr, &defn_vec_ptr, IDL_msp);
431            break;
432        default:
433#ifdef DEBUG_INTERP
434            printf("rpc_ss_ndr_marsh_pointee: unrecognized type %d\n",
435                        pointee_type);
436            exit(0);
437#endif
438            DCETHREAD_RAISE(rpc_x_coding_error);
439
440    }
441    rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
442}
443
444/******************************************************************************/
445/*                                                                            */
446/*  Marshall the pointees of a structure                                      */
447/*                                                                            */
448/******************************************************************************/
449void rpc_ss_ndr_m_struct_pointees
450(
451    /* [in] */  idl_byte struct_type,   /* DT_FIXED_STRUCT or DT_CONF_STRUCT */
452    /* [in] */  idl_ulong_int defn_index,  /* Index of structure dedecription */
453    /* [in] */  rpc_void_p_t struct_addr,
454    IDL_msp_t IDL_msp
455)
456{
457    idl_ulong_int offset_index;
458    idl_byte *defn_vec_ptr;
459    idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */
460    idl_ulong_int *offset_vec_ptr;
461    idl_byte type_byte;
462    idl_ulong_int offset;
463    idl_ulong_int field_defn_index;
464    idl_byte *field_defn_ptr;
465    idl_ulong_int conf_dims;    /* Number of dimensions of conformance info */
466    IDL_bound_pair_t *conf_bounds;   /* Bounds list from conformance info */
467    idl_ulong_int *Z_values;
468    IDL_bound_pair_t *range_list;
469    idl_boolean type_has_pointers;
470    IDL_pointee_desc_t pointee_desc;    /* Description of pointee */
471    idl_ulong_int switch_index; /* Index of switch field for non-encapsulated
472                                                                        union */
473    idl_boolean add_null;       /* Dummy argument in procedure call */
474
475    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
476    IDL_GET_LONG_FROM_VECTOR(offset_index,defn_vec_ptr);
477    struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index;
478    offset_vec_ptr = struct_offset_vec_ptr + 1;
479                                        /* Skip over size at start of offsets */
480
481    if (struct_type == IDL_DT_CONF_STRUCT)
482    {
483        /* Next integer in the definition vector is a fully flattened array rep
484            for the conformant array field */
485        IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
486    }
487
488    pointee_desc.dimensionality = 0;
489    do {
490        type_byte = *defn_vec_ptr;
491        defn_vec_ptr++;
492        switch(type_byte)
493        {
494            /* For fields that do not include pointers, simply advance
495                the definition and offset pointers in step */
496            case IDL_DT_CS_SHADOW:
497                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
498                break;
499            case IDL_DT_BYTE:
500            case IDL_DT_CHAR:
501            case IDL_DT_BOOLEAN:
502            case IDL_DT_DOUBLE:
503            case IDL_DT_ENUM:
504            case IDL_DT_FLOAT:
505            case IDL_DT_SMALL:
506            case IDL_DT_SHORT:
507            case IDL_DT_LONG:
508            case IDL_DT_HYPER:
509            case IDL_DT_USMALL:
510            case IDL_DT_USHORT:
511            case IDL_DT_ULONG:
512            case IDL_DT_UHYPER:
513            case IDL_DT_IGNORE:
514            case IDL_DT_V1_ENUM:
515            case IDL_DT_ERROR_STATUS:
516                offset_vec_ptr++;
517                break;
518            case IDL_DT_FIXED_ARRAY:
519                /* Properties byte */
520                type_has_pointers =
521                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
522                defn_vec_ptr++;
523                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
524                                                    /* Full array definition */
525                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
526                if (type_has_pointers)
527                {
528                    offset = *offset_vec_ptr;
529                    rpc_ss_ndr_m_dfc_arr_ptees(field_defn_index,
530                                        (idl_byte *)struct_addr+offset,
531                                        NULL, NULL, 0, IDL_msp);
532                }
533                offset_vec_ptr++;
534                break;
535            case IDL_DT_VARYING_ARRAY:
536                /* Properties byte */
537                type_has_pointers =
538                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
539                defn_vec_ptr++;
540                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
541                                                    /* Full array definition */
542                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
543                offset = *offset_vec_ptr;
544                if (type_has_pointers)
545                {
546                    rpc_ss_ndr_m_dvo_arr_ptees(field_defn_index,
547                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
548                            struct_addr, struct_offset_vec_ptr, 0,
549                            IDL_msp);
550                }
551                offset_vec_ptr++;
552                break;
553            case IDL_DT_CONF_ARRAY:
554                /* Properties byte */
555                type_has_pointers =
556                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
557                defn_vec_ptr++;
558                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
559                                                    /* Full array definition */
560                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
561                /* Note - must be last field of struct */
562                if (type_has_pointers)
563                {
564                    offset = *offset_vec_ptr;
565                    field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
566                    conf_dims = (idl_ulong_int)*field_defn_ptr;
567                    field_defn_ptr++;
568                    conf_bounds = NULL;
569                    rpc_ss_build_bounds_list( &field_defn_ptr,
570                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
571                            struct_addr, struct_offset_vec_ptr, conf_dims,
572                                              &conf_bounds, IDL_msp );
573                    rpc_ss_ndr_m_f_or_c_arr_ptees(
574                        (rpc_void_p_t)((idl_byte *)struct_addr+offset),
575                        conf_dims, conf_bounds, field_defn_ptr, IDL_msp );
576                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
577                                            (byte_p_t)conf_bounds);
578                }
579                break;
580            case IDL_DT_OPEN_ARRAY:
581                /* Properties byte */
582                type_has_pointers =
583                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
584                defn_vec_ptr++;
585                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
586                                                    /* Full array definition */
587                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
588                /* Note - must be last field of struct */
589                if (type_has_pointers)
590                {
591                    offset = *offset_vec_ptr;
592                    field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
593                    conf_dims = (idl_ulong_int)*field_defn_ptr;
594                    field_defn_ptr++;
595                    conf_bounds = NULL;
596                    rpc_ss_build_bounds_list( &field_defn_ptr,
597                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
598                            struct_addr, struct_offset_vec_ptr, conf_dims,
599                                              &conf_bounds, IDL_msp );
600                    Z_values = NULL;
601                    rpc_ss_Z_values_from_bounds( conf_bounds, conf_dims,
602                                                           &Z_values, IDL_msp );
603                    range_list = NULL;
604                    rpc_ss_build_range_list( &field_defn_ptr,
605                                (rpc_void_p_t)((idl_byte *)struct_addr+offset),
606                                 struct_addr, struct_offset_vec_ptr, conf_dims,
607                                 conf_bounds, &range_list, &add_null, IDL_msp );
608                    rpc_ss_ndr_m_v_or_o_arr_ptees(
609                        (rpc_void_p_t)((idl_byte *)struct_addr+offset),
610                        Z_values, conf_dims, range_list, field_defn_ptr,
611                        IDL_msp );
612                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
613                                            (byte_p_t)range_list);
614                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
615                                            (byte_p_t)Z_values);
616                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
617                                            (byte_p_t)conf_bounds);
618                }
619                break;
620            case IDL_DT_ENC_UNION:
621                /* Properties byte */
622                type_has_pointers =
623                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
624                defn_vec_ptr++;
625                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
626                if (type_has_pointers)
627                {
628                    offset = *offset_vec_ptr;
629                    rpc_ss_ndr_m_enc_union_or_ptees(
630                                              (idl_byte *)struct_addr+offset,
631                                           field_defn_index, idl_true, IDL_msp);
632                }
633                offset_vec_ptr++;
634                break;
635            case IDL_DT_N_E_UNION:
636                /* Properties byte */
637                type_has_pointers =
638                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
639                defn_vec_ptr++;
640                IDL_GET_LONG_FROM_VECTOR(switch_index, defn_vec_ptr);
641                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
642                if (type_has_pointers)
643                {
644                    offset = *offset_vec_ptr;
645                    rpc_ss_ndr_m_n_e_union_or_ptees(
646                                   (idl_byte *)struct_addr+offset, switch_index,
647                                   field_defn_index, struct_addr,
648                                   struct_offset_vec_ptr, idl_true, IDL_msp);
649                }
650                offset_vec_ptr++;
651                break;
652            case IDL_DT_FULL_PTR:
653                defn_vec_ptr++;     /* Properties byte */
654                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
655                offset = *offset_vec_ptr;
656                offset_vec_ptr++;
657                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
658                if (*(rpc_void_p_t *)((idl_byte *)struct_addr+offset) != NULL)
659                {
660                    rpc_ss_pointee_desc_from_data( field_defn_ptr,
661                            *(rpc_void_p_t *)((idl_byte *)struct_addr+offset),
662                            struct_addr,
663                            struct_offset_vec_ptr, &pointee_desc, IDL_msp );
664                    rpc_ss_ndr_marsh_pointee( field_defn_ptr,
665                            *(rpc_void_p_t *)((idl_byte *)struct_addr+offset),
666                            idl_true, &pointee_desc, IDL_msp );
667                }
668                break;
669            case IDL_DT_UNIQUE_PTR:
670                defn_vec_ptr++;     /* Properties byte */
671                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
672                offset = *offset_vec_ptr;
673                offset_vec_ptr++;
674                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
675                if (*(rpc_void_p_t *)((idl_byte *)struct_addr+offset) != NULL)
676                {
677                    rpc_ss_pointee_desc_from_data( field_defn_ptr,
678                            *(rpc_void_p_t *)((idl_byte *)struct_addr+offset),
679                            struct_addr,
680                            struct_offset_vec_ptr, &pointee_desc, IDL_msp );
681                    rpc_ss_ndr_marsh_pointee( field_defn_ptr,
682                            *(rpc_void_p_t *)((idl_byte *)struct_addr+offset),
683                            idl_false, &pointee_desc, IDL_msp );
684                }
685                break;
686            case IDL_DT_REF_PTR:
687                defn_vec_ptr++;     /* Properties byte */
688                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
689                offset = *offset_vec_ptr;
690                offset_vec_ptr++;
691                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
692                rpc_ss_pointee_desc_from_data( field_defn_ptr,
693                            *(rpc_void_p_t *)((idl_byte *)struct_addr+offset),
694                            struct_addr,
695                            struct_offset_vec_ptr, &pointee_desc, IDL_msp );
696                rpc_ss_ndr_marsh_pointee( field_defn_ptr,
697                            *(rpc_void_p_t *)((idl_byte *)struct_addr+offset),
698                            idl_false, &pointee_desc, IDL_msp );
699                break;
700            case IDL_DT_TRANSMIT_AS:
701            case IDL_DT_REPRESENT_AS:
702            case IDL_DT_CS_TYPE:
703                defn_vec_ptr++;     /* Properties byte */
704                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
705                offset_vec_ptr++;
706                break;
707            case IDL_DT_RANGE:
708                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
709                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
710                break;
711            case IDL_DT_STRING:
712            case IDL_DT_NDR_ALIGN_2:
713            case IDL_DT_NDR_ALIGN_4:
714            case IDL_DT_NDR_ALIGN_8:
715            case IDL_DT_BEGIN_NESTED_STRUCT:
716            case IDL_DT_END_NESTED_STRUCT:
717            case IDL_DT_V1_ARRAY:
718            case IDL_DT_V1_STRING:
719            case IDL_DT_CS_ATTRIBUTE:
720            case IDL_DT_CS_ARRAY:
721            case IDL_DT_CS_RLSE_SHADOW:
722            case IDL_DT_EOL:
723                break;
724            default:
725#ifdef DEBUG_INTERP
726                printf("rpc_ss_ndr_m_struct_pointees:unrecognized type %d\n",
727                        type_byte);
728                exit(0);
729#endif
730                DCETHREAD_RAISE(rpc_x_coding_error);
731        }
732    } while (type_byte != IDL_DT_EOL);
733    rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
734
735}
736
737/******************************************************************************/
738/*                                                                            */
739/* Marshall the pointees of a fixed or conformant array                       */
740/*                                                                            */
741/******************************************************************************/
742static void rpc_ss_ndr_m_f_or_c_arr_ptees
743(
744    /* [in] */  rpc_void_p_t array_addr,
745    /* [in] */  idl_ulong_int dimensionality,
746    /* [in] */  IDL_bound_pair_t *bounds_list,
747    /* [in] */  idl_byte *defn_vec_ptr, /* On entry points to array base info */
748    IDL_msp_t IDL_msp
749)
750{
751    idl_byte base_type;
752    idl_ulong_int element_count;
753    unsigned32 i;
754    idl_ulong_int element_defn_index;
755    idl_ulong_int element_offset_index;
756    idl_ulong_int element_size;
757    idl_byte *element_defn_ptr;
758    rpc_void_p_t *array_elt_addr;
759    IDL_pointee_desc_t pointee_desc;
760
761    element_count = 1;
762    for (i=0; i<dimensionality; i++)
763    {
764        element_count *= (bounds_list[i].upper - bounds_list[i].lower + 1);
765    }
766
767    base_type = *defn_vec_ptr;
768
769    if (base_type == IDL_DT_FIXED_STRUCT)
770    {
771        defn_vec_ptr += 2;  /* DT_FIXED_STRUCT and properties byte */
772        /* Array of structures containing pointers */
773        IDL_GET_LONG_FROM_VECTOR(element_defn_index, defn_vec_ptr);
774        element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index;
775        IDL_GET_LONG_FROM_VECTOR(element_offset_index, element_defn_ptr);
776        element_size = *(IDL_msp->IDL_offset_vec + element_offset_index);
777        for (i=0; i<element_count; i++)
778        {
779            rpc_ss_ndr_m_struct_pointees( base_type, element_defn_index,
780                                            array_addr, IDL_msp );
781            array_addr = (rpc_void_p_t)((idl_byte *)array_addr + element_size);
782        }
783    }
784    else if (base_type == IDL_DT_ENC_UNION)
785    {
786        defn_vec_ptr += 2;  /* DT_ENC_UNION and properties byte */
787        /* Array of unions containing pointers */
788        IDL_GET_LONG_FROM_VECTOR(element_defn_index, defn_vec_ptr);
789        element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index;
790        IDL_GET_LONG_FROM_VECTOR(element_offset_index, element_defn_ptr);
791        element_size = *(IDL_msp->IDL_offset_vec + element_offset_index);
792        for (i=0; i<element_count; i++)
793        {
794            rpc_ss_ndr_m_enc_union_or_ptees( array_addr, element_defn_index,
795                                             idl_true, IDL_msp );
796            array_addr = (rpc_void_p_t)((idl_byte *)array_addr + element_size);
797        }
798    }
799    else
800    {
801        defn_vec_ptr++;     /* Move to pointee type */
802        /* Array of pointers */
803        array_elt_addr = (rpc_void_p_t *)(array_addr);
804        pointee_desc.dimensionality = 0;
805        for (i=0; i<element_count; i++)
806        {
807            if (*(rpc_void_p_t *)array_elt_addr != NULL)
808            {
809                rpc_ss_pointee_desc_from_data( defn_vec_ptr,
810                                           *(rpc_void_p_t *)array_elt_addr,
811                                           NULL, NULL, &pointee_desc, IDL_msp );
812                rpc_ss_ndr_marsh_pointee( defn_vec_ptr, *array_elt_addr,
813                                        (base_type == IDL_DT_FULL_PTR),
814                                        &pointee_desc, IDL_msp );
815            }
816            array_elt_addr++;
817        }
818        rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
819    }
820}
821
822/******************************************************************************/
823/*                                                                            */
824/*  Starting from the index in the definition vector for a fixed or           */
825/*  conformant array, marshall the array's pointees                           */
826/*                                                                            */
827/******************************************************************************/
828void rpc_ss_ndr_m_dfc_arr_ptees
829(
830    /* [in] */  idl_ulong_int defn_index,   /* Index of array description */
831    /* [in] */  rpc_void_p_t array_addr,
832    /* [in] */  rpc_void_p_t struct_addr,   /* Address of structure array is
833                      part of. NULL if array is a parameter or not conformant */
834    /* [in] */  idl_ulong_int *struct_offset_vec_ptr,
835                            /*  NULL if array is a parameter or not conformant*/
836    /* [in] */  idl_ulong_int flags,
837    IDL_msp_t IDL_msp
838)
839{
840    idl_byte *defn_vec_ptr;
841    idl_ulong_int dimensionality;
842    IDL_bound_pair_t *bounds_list;
843
844    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
845    dimensionality = (idl_ulong_int)*defn_vec_ptr;
846    defn_vec_ptr++;
847    /* By design defn_vec_ptr is longword aligned */
848    if (IDL_M_FLAGS_TEST(flags,IDL_M_CONF_ARRAY))
849    {
850        bounds_list = NULL;
851        rpc_ss_build_bounds_list( &defn_vec_ptr, array_addr, struct_addr,
852                                    struct_offset_vec_ptr, dimensionality,
853                                    &bounds_list, IDL_msp );
854    }
855    else
856    {
857	if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
858	    rpc_ss_fixed_bounds_from_vector(dimensionality, defn_vec_ptr,
859					    &bounds_list, IDL_msp);
860	else
861	    bounds_list = (IDL_bound_pair_t *)defn_vec_ptr;
862        defn_vec_ptr += dimensionality * sizeof(IDL_bound_pair_t);
863    }
864    rpc_ss_ndr_m_f_or_c_arr_ptees( array_addr, dimensionality, bounds_list,
865                                  defn_vec_ptr, IDL_msp );
866    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] == NDR_LOCAL_INT_REP)
867    {
868	if (IDL_M_FLAGS_TEST(flags,IDL_M_CONF_ARRAY))
869	  rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
870    }
871    else
872	rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
873}
874
875/******************************************************************************/
876/*                                                                            */
877/* Marshall the pointees of a varying or open array                           */
878/*                                                                            */
879/******************************************************************************/
880static void rpc_ss_ndr_m_v_or_o_arr_ptees
881(
882    /* [in] */  rpc_void_p_t array_addr,
883    /* [in] */  idl_ulong_int *Z_values,
884    /* [in] */  idl_ulong_int dimensionality,
885    /* [in] */  IDL_bound_pair_t *range_list,
886    /* [in] */  idl_byte *defn_vec_ptr, /* On entry points at base type */
887    IDL_msp_t IDL_msp
888)
889{
890    idl_ulong_int element_defn_index;
891    idl_ulong_int element_size;
892    idl_byte base_type;
893    idl_byte *element_defn_ptr;
894    idl_ulong_int element_offset_index;
895    IDL_varying_control_t *control_data;    /* List of data used to control
896                                                marshalling loops */
897    int i;
898    idl_byte *inner_slice_address;  /* Address of 1-dim subset of array */
899    int dim;    /* Index through array dimensions */
900    IDL_pointee_desc_t pointee_desc;
901
902    base_type = *defn_vec_ptr;
903
904    element_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
905    defn_vec_ptr++;
906
907    if ( (base_type == IDL_DT_FIXED_STRUCT) || (base_type == IDL_DT_ENC_UNION) )
908    {
909        IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
910        element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index;
911        IDL_GET_LONG_FROM_VECTOR(element_offset_index, element_defn_ptr);
912        element_size = *(IDL_msp->IDL_offset_vec + element_offset_index);
913    }
914
915    control_data = (IDL_varying_control_t *)rpc_ss_mem_alloc(
916                                &IDL_msp->IDL_mem_handle,
917                                dimensionality * sizeof(IDL_varying_control_t));
918    control_data[dimensionality-1].subslice_size = element_size;
919    control_data[dimensionality-1].index_value =
920                                            range_list[dimensionality-1].lower;
921    for (i=dimensionality-2; i>=0; i--)
922    {
923        control_data[i].index_value = range_list[i].lower;
924        control_data[i].subslice_size = control_data[i+1].subslice_size
925                                                            * Z_values[i+1];
926    }
927
928    pointee_desc.dimensionality = 0;
929    do {
930        inner_slice_address = (idl_byte *)array_addr;
931        for (i=0; (unsigned32)i<dimensionality; i++)
932        {
933            inner_slice_address += control_data[i].index_value
934                                        * control_data[i].subslice_size;
935        }
936        for (i = range_list[dimensionality-1].lower;
937             i < range_list[dimensionality-1].upper;
938             i++)
939        {
940            if (base_type == IDL_DT_FIXED_STRUCT)
941            {
942                rpc_ss_ndr_m_struct_pointees( base_type, element_defn_index,
943                                                inner_slice_address, IDL_msp );
944                inner_slice_address += element_size;
945            }
946            else if (base_type == IDL_DT_ENC_UNION)
947            {
948                rpc_ss_ndr_m_enc_union_or_ptees(inner_slice_address,
949                                                element_defn_index,
950                                                idl_true, IDL_msp );
951                inner_slice_address += element_size;
952            }
953            else
954            {
955                /* Array of pointers */
956                if (*(rpc_void_p_t *)inner_slice_address != NULL)
957                {
958                    rpc_ss_pointee_desc_from_data( defn_vec_ptr,
959                                           *(rpc_void_p_t *)inner_slice_address,
960                                           NULL, NULL, &pointee_desc, IDL_msp );
961                    rpc_ss_ndr_marsh_pointee( defn_vec_ptr,
962                                          *(rpc_void_p_t *)inner_slice_address,
963                                          (base_type == IDL_DT_FULL_PTR),
964                                          &pointee_desc, IDL_msp );
965                }
966                inner_slice_address += sizeof(rpc_void_p_t *);
967            }
968        }
969        dim = dimensionality - 2;
970        while (dim >= 0)
971        {
972            control_data[dim].index_value++;
973            if (control_data[dim].index_value < (unsigned32)range_list[dim].upper)
974                break;
975            control_data[dim].index_value = range_list[dim].lower;
976            dim--;
977        }
978    } while (dim >= 0);
979    rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
980
981    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)control_data);
982}
983
984/******************************************************************************/
985/*                                                                            */
986/*  Starting from the index in the definition vector for a varying or         */
987/*  open array, marshall the array's pointees                                */
988/*                                                                            */
989/******************************************************************************/
990void rpc_ss_ndr_m_dvo_arr_ptees
991(
992    /* [in] */  idl_ulong_int defn_index,   /* Index of array description */
993    /* [in] */  rpc_void_p_t array_addr,
994    /* [in] */  rpc_void_p_t struct_addr,   /* Address of structure array is
995                                     part of. NULL if array is a parameter */
996    /* [in] */  idl_ulong_int *struct_offset_vec_ptr,
997                                           /*  NULL if array is a parameter */
998    /* [in] */  idl_ulong_int flags,
999    IDL_msp_t IDL_msp
1000)
1001{
1002    idl_byte *defn_vec_ptr;
1003    idl_ulong_int dimensionality;
1004    IDL_bound_pair_t *bounds_list;
1005    idl_ulong_int *Z_values;
1006    IDL_bound_pair_t *range_list;
1007    idl_boolean add_null;       /* Dummy argument in procedure call */
1008
1009    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
1010    dimensionality = (idl_ulong_int)*defn_vec_ptr;
1011    defn_vec_ptr++;
1012    /* By design defn_vec_ptr is longword aligned */
1013    if (IDL_M_FLAGS_TEST(flags,IDL_M_CONF_ARRAY))
1014    {
1015        bounds_list = NULL;
1016        rpc_ss_build_bounds_list( &defn_vec_ptr, array_addr, struct_addr,
1017                                    struct_offset_vec_ptr, dimensionality,
1018                                    &bounds_list, IDL_msp );
1019    }
1020    else
1021    {
1022	if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1023	    rpc_ss_fixed_bounds_from_vector(dimensionality, defn_vec_ptr,
1024					    &bounds_list, IDL_msp);
1025	else
1026	    bounds_list = (IDL_bound_pair_t *)defn_vec_ptr;
1027        defn_vec_ptr += dimensionality * sizeof(IDL_bound_pair_t);
1028    }
1029    Z_values = NULL;
1030    rpc_ss_Z_values_from_bounds( bounds_list, dimensionality, &Z_values,
1031                                                                   IDL_msp );
1032    range_list = NULL;
1033    rpc_ss_build_range_list( &defn_vec_ptr, array_addr, struct_addr,
1034                             struct_offset_vec_ptr, dimensionality, bounds_list,
1035                             &range_list, &add_null, IDL_msp );
1036    rpc_ss_ndr_m_v_or_o_arr_ptees( array_addr, Z_values, dimensionality,
1037                                    range_list, defn_vec_ptr, IDL_msp );
1038    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)range_list);
1039    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1040    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] == NDR_LOCAL_INT_REP)
1041    {
1042	if (IDL_M_FLAGS_TEST(flags,IDL_M_CONF_ARRAY))
1043	    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1044				 (byte_p_t)bounds_list);
1045    }
1046    else
1047	rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1048
1049}
1050
1051/******************************************************************************/
1052/*                                                                            */
1053/*  Find out if a pointee is a non-fixed array or non-encapsulated union.     */
1054/*  If it is, use data in memory to set up the data structures needed for     */
1055/*  marshalling it                                                            */
1056/*                                                                            */
1057/******************************************************************************/
1058void rpc_ss_pointee_desc_from_data
1059(
1060    /* [in] */  idl_byte *defn_vec_ptr, /* Points at definition of pointee */
1061    /* [in] */  rpc_void_p_t array_addr,    /* Need only be non-NULL if pointee
1062                                requires string bound/data limit calculations */
1063    /* [in] */  rpc_void_p_t struct_addr,   /* Address of structure pointer is
1064                                       part of NULL if pointer is a parameter */
1065    /* [in] */  idl_ulong_int *struct_offset_vec_ptr,
1066                                           /*  NULL if pointer is a parameter */
1067    /* [out] */ IDL_pointee_desc_t *p_pointee_desc, /* Pointer to data structure
1068                                     to be filled in with pointee description */
1069    IDL_msp_t IDL_msp
1070)
1071{
1072    idl_ulong_int array_defn_index;
1073    idl_byte *array_defn_ptr;
1074    idl_boolean add_null;       /* Dummy argument in procedure call */
1075    idl_ulong_int dimensionality;
1076
1077    if (*defn_vec_ptr == IDL_DT_STRING)
1078        defn_vec_ptr++;
1079    p_pointee_desc->pointee_type = *defn_vec_ptr;
1080    if (p_pointee_desc->pointee_type == IDL_DT_N_E_UNION)
1081    {
1082        p_pointee_desc->struct_addr = struct_addr;
1083        p_pointee_desc->struct_offset_vec_ptr = struct_offset_vec_ptr;
1084        return;
1085    }
1086    else
1087        if ( (p_pointee_desc->pointee_type != IDL_DT_VARYING_ARRAY)
1088        && (p_pointee_desc->pointee_type != IDL_DT_CONF_ARRAY)
1089        && (p_pointee_desc->pointee_type != IDL_DT_OPEN_ARRAY) )
1090    {
1091        return;
1092    }
1093
1094    /* Remainder of this routine only executed for non-fixed array */
1095    defn_vec_ptr++;
1096    p_pointee_desc->base_type_has_pointers =
1097                            IDL_PROP_TEST( *defn_vec_ptr, IDL_PROP_HAS_PTRS );
1098    defn_vec_ptr++;
1099    IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );   /* Full array definition */
1100    IDL_GET_LONG_FROM_VECTOR( array_defn_index, defn_vec_ptr );
1101    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1102    dimensionality = (idl_ulong_int)*array_defn_ptr;
1103    array_defn_ptr++;
1104
1105    /* Minimize the number of malloc's used to build the data structure */
1106    /* In code that follows, range list and bounds list will be allocated
1107        out of this memory, if necessary */
1108    if (dimensionality > p_pointee_desc->dimensionality)
1109    {
1110        if (p_pointee_desc->dimensionality > 0)
1111        {
1112            /* Some array description storage already exists, release it */
1113            rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1114                                            (byte_p_t)p_pointee_desc->Z_values);
1115        }
1116        p_pointee_desc->Z_values = (idl_ulong_int *) rpc_ss_mem_alloc(
1117                                  &IDL_msp->IDL_mem_handle,
1118                                    dimensionality *
1119                                     ( sizeof(idl_ulong_int) /* Z_values */
1120                                      + 2 * sizeof(IDL_bound_pair_t)
1121                                        /* bounds list and range list */ ) );
1122    }
1123    p_pointee_desc->dimensionality = dimensionality;
1124
1125    switch(p_pointee_desc->pointee_type)
1126    {
1127        case IDL_DT_VARYING_ARRAY:
1128	    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP){
1129		/* Use storage after Z_values and range list for bounds list */
1130		p_pointee_desc->bounds_list =  (IDL_bound_pair_t *)
1131		    (p_pointee_desc->Z_values + p_pointee_desc->dimensionality)
1132		    + p_pointee_desc->dimensionality;
1133		rpc_ss_fixed_bounds_from_vector(p_pointee_desc->dimensionality,
1134						array_defn_ptr,
1135						&(p_pointee_desc->bounds_list),
1136						IDL_msp);
1137	    }
1138	    else
1139		p_pointee_desc->bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
1140            /* Build the range list in store allocated for the pointee desc,
1141                following the Z-values */
1142            p_pointee_desc->range_list =  (IDL_bound_pair_t *)
1143                    (p_pointee_desc->Z_values + p_pointee_desc->dimensionality);
1144            rpc_ss_Z_values_from_bounds( p_pointee_desc->bounds_list,
1145                                         p_pointee_desc->dimensionality,
1146                                         &(p_pointee_desc->Z_values),
1147                                         IDL_msp );
1148            array_defn_ptr += p_pointee_desc->dimensionality
1149                                    * IDL_FIXED_BOUND_PAIR_WIDTH;
1150            rpc_ss_build_range_list( &array_defn_ptr, array_addr, struct_addr,
1151                                     struct_offset_vec_ptr,
1152                                     p_pointee_desc->dimensionality,
1153                                     p_pointee_desc->bounds_list,
1154                                     &(p_pointee_desc->range_list),
1155                                     &add_null, IDL_msp );
1156            break;
1157        case IDL_DT_CONF_ARRAY:
1158            /* Build the bounds list in store allocated for the pointee desc,
1159                following the Z-values */
1160            p_pointee_desc->bounds_list =  (IDL_bound_pair_t *)
1161                    (p_pointee_desc->Z_values + p_pointee_desc->dimensionality);
1162            rpc_ss_build_bounds_list( &array_defn_ptr, array_addr, struct_addr,
1163                                     struct_offset_vec_ptr,
1164                                     p_pointee_desc->dimensionality,
1165                                     &(p_pointee_desc->bounds_list),
1166                                     IDL_msp );
1167            rpc_ss_Z_values_from_bounds( p_pointee_desc->bounds_list,
1168                                         p_pointee_desc->dimensionality,
1169                                         &(p_pointee_desc->Z_values),
1170                                         IDL_msp );
1171            break;
1172        case IDL_DT_OPEN_ARRAY:
1173            /* Store allocated for the pointee desc is organized
1174                Z-values, bounds list, range list */
1175            p_pointee_desc->bounds_list =  (IDL_bound_pair_t *)
1176                    (p_pointee_desc->Z_values + p_pointee_desc->dimensionality);
1177            p_pointee_desc->range_list =  p_pointee_desc->bounds_list
1178                                               + p_pointee_desc->dimensionality;
1179            rpc_ss_build_bounds_list( &array_defn_ptr, array_addr, struct_addr,
1180                                     struct_offset_vec_ptr,
1181                                     p_pointee_desc->dimensionality,
1182                                     &(p_pointee_desc->bounds_list),
1183                                     IDL_msp );
1184            rpc_ss_Z_values_from_bounds( p_pointee_desc->bounds_list,
1185                                         p_pointee_desc->dimensionality,
1186                                         &(p_pointee_desc->Z_values),
1187                                         IDL_msp );
1188            rpc_ss_build_range_list( &array_defn_ptr, array_addr, struct_addr,
1189                                     struct_offset_vec_ptr,
1190                                     p_pointee_desc->dimensionality,
1191                                     p_pointee_desc->bounds_list,
1192                                     &(p_pointee_desc->range_list),
1193                                     &add_null, IDL_msp );
1194            break;
1195        default:
1196            DCETHREAD_RAISE( rpc_x_coding_error );
1197    }
1198    p_pointee_desc->array_base_defn_ptr = array_defn_ptr;
1199}
1200