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**      ndrui2.c
80**
81**  FACILITY:
82**
83**      Interface Definition Language (IDL) Compiler
84**
85**  ABSTRACT:
86**
87**      NDR unmarshalling interpreter routines for - pointers
88**
89*/
90#if HAVE_CONFIG_H
91#include <config.h>
92#endif
93
94#include <dce/idlddefs.h>
95#include <ndrui.h>
96#include <lsysdep.h>
97#include <assert.h>
98
99static void rpc_ss_init_new_store_ptrs
100(
101    idl_byte storage_type,
102    idl_byte *defn_vec_ptr,
103    rpc_void_p_t storage_addr,
104    idl_ulong_int *Z_values,
105    IDL_msp_t IDL_msp
106);
107
108/******************************************************************************/
109/*                                                                            */
110/*  Unmarshall a pointer that is the target of a pointer                      */
111/*                                                                            */
112/******************************************************************************/
113static void rpc_ss_ndr_unmar_ptr_ptee
114(
115    /* [in] */ idl_byte pointee_type,
116    /* [in] */ rpc_void_p_t p_node,    /* Pointer to storage for pointee */
117    /* [in] */ idl_byte *defn_vec_ptr,  /* On entry points at pointee type */
118    IDL_msp_t IDL_msp
119)
120{
121    IDL_pointee_desc_t pointee_desc;    /* Description of pointee's pointee */
122    intptr_t node_number = 0;
123    idl_ulong_int unique_flag;  /* Wire form of [unique] pointer */
124
125    switch(pointee_type)
126    {
127        case IDL_DT_FULL_PTR:
128	{
129	    idl_ulong_int _node;
130            /* Unmarshall the node number */
131            IDL_UNMAR_ULONG( &_node );
132	    node_number = (intptr_t) _node;
133            *(rpc_void_p_t *)p_node = (rpc_void_p_t)node_number;
134            defn_vec_ptr++;
135            pointee_desc.dimensionality = 0;
136            pointee_desc.struct_addr = NULL;
137            pointee_desc.struct_offset_vec_ptr = NULL;
138            rpc_ss_ndr_unmar_pointee_desc( pointee_type, defn_vec_ptr,
139                                              &pointee_desc, p_node, IDL_msp );
140            rpc_ss_ndr_unmar_pointee( pointee_type, defn_vec_ptr, &pointee_desc,
141                                                             p_node, IDL_msp );
142            rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp );
143            break;
144	}
145        case IDL_DT_UNIQUE_PTR:
146            IDL_UNMAR_ULONG( &unique_flag );
147            if (unique_flag == 0)
148                *(rpc_void_p_t *)p_node = NULL;
149            else
150            {
151                defn_vec_ptr++;
152                pointee_desc.dimensionality = 0;
153                pointee_desc.struct_addr = NULL;
154                pointee_desc.struct_offset_vec_ptr = NULL;
155                rpc_ss_ndr_unmar_pointee_desc( pointee_type, defn_vec_ptr,
156                                             &pointee_desc, p_node, IDL_msp );
157                if (*(rpc_void_p_t *)p_node == NULL)
158                {
159                    *(rpc_void_p_t *)p_node = IDL_NEW_NODE;
160                }
161                rpc_ss_ndr_unmar_pointee( pointee_type, defn_vec_ptr,
162                                             &pointee_desc, p_node, IDL_msp );
163                rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp );
164            }
165            break;
166        case IDL_DT_REF_PTR:
167            defn_vec_ptr++;
168            pointee_desc.struct_addr = NULL;
169            pointee_desc.struct_offset_vec_ptr = NULL;
170            pointee_desc.dimensionality = 0;
171            rpc_ss_ndr_unmar_pointee_desc( pointee_type, defn_vec_ptr,
172                                              &pointee_desc, p_node, IDL_msp );
173            rpc_ss_ndr_unmar_pointee( pointee_type, defn_vec_ptr, &pointee_desc,
174                                                             p_node, IDL_msp );
175            rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp );
176            break;
177    }
178}
179
180/******************************************************************************/
181/*                                                                            */
182/*  Unmarshall the target of a pointer                                        */
183/*                                                                            */
184/******************************************************************************/
185void rpc_ss_ndr_unmar_pointee
186(
187    /* [in] */ idl_byte pointer_type,   /* [ptr], [unique] or [ref] */
188    /* [in] */ idl_byte *defn_vec_ptr,  /* On entry points at pointee type */
189    /* [in] */ IDL_pointee_desc_t *p_pointee_desc, /* Pointer to data structure
190                                   containing pointee description.
191                                 NULL if pointee cannot be a non-fixed array */
192    /* [in,out] */ rpc_void_p_t *p_pointer,
193                    /* Entry - for a full pointer points to a node number
194                             - for non-full pointer
195                                if points to NULL, storage must be allocated
196                                otherwise points to address of storage for
197                                                                    pointee
198                       Exit - points to the address of the pointee */
199    IDL_msp_t IDL_msp
200)
201{
202    idl_ulong_int node_number = 0;
203    idl_ulong_int node_size = 0;
204    rpc_void_p_t p_node;    /* Pointer to storage for pointee */
205    long already_unmarshalled;
206    long new_node;
207    idl_byte pointee_type;
208    idl_boolean type_has_pointers;
209    idl_ulong_int pointee_defn_index;
210    idl_byte *struct_defn_ptr;
211    idl_ulong_int offset_index;
212    idl_ulong_int *struct_offset_vec_ptr = NULL; /* Start of offsets for this struct */
213    idl_ulong_int array_defn_index;
214    idl_byte *array_defn_ptr = NULL;
215    idl_ulong_int conf_dims = 0;    /* Number of dimensions of conformance info */
216    idl_ulong_int *Z_values = NULL;
217    idl_byte *constr_defn_ptr;   /* Pointer to definition of constructed type */
218    idl_ulong_int switch_value;  /* Also used for [cs_char] machinery */
219    IDL_cs_shadow_elt_t *struct_cs_shadow = NULL;
220    IDL_bound_pair_t range_bounds;
221
222    if ( (pointer_type == IDL_DT_FULL_PTR)
223            || (pointer_type == IDL_DT_UNIQUE_PTR) )
224    {
225        node_number = (idl_ulong_int)*p_pointer;
226        if (node_number == 0)
227        {
228            /* Pointee of a null [ptr] or [unique] pointer */
229            return;
230        }
231    }
232
233    pointee_type = *defn_vec_ptr;
234    if (pointee_type == IDL_DT_STRING)
235    {
236        /* Varying/open array code will do the right thing */
237        defn_vec_ptr++;
238        pointee_type = *defn_vec_ptr;
239    }
240
241    IDL_INIT_RANGE(range_bounds);
242    if (pointee_type == IDL_DT_RANGE)
243    {
244        IDL_GET_RANGE_FROM_VECTOR(range_bounds, defn_vec_ptr);
245        pointee_type = *defn_vec_ptr;
246    }
247
248    if (pointee_type == IDL_DT_CONF_STRUCT)
249    {
250        /*
251         * Return if the pointer is a non-null full pointer and
252         * the pointee has already been unmarshalled.
253         */
254        if (pointer_type == IDL_DT_FULL_PTR
255            && p_pointee_desc->already_unmarshalled)
256            return;
257        constr_defn_ptr = defn_vec_ptr + 2; /* Next byte after properties */
258        IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,constr_defn_ptr);
259        struct_defn_ptr = IDL_msp->IDL_type_vec + pointee_defn_index;
260        IDL_GET_LONG_FROM_VECTOR(offset_index,struct_defn_ptr);
261        struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index;
262        IDL_GET_LONG_FROM_VECTOR(array_defn_index,struct_defn_ptr);
263        array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
264        conf_dims = (idl_ulong_int)*array_defn_ptr;
265        Z_values = NULL;
266        rpc_ss_ndr_unmar_Z_values( conf_dims, &Z_values, IDL_msp );
267#define struct_shadow_length switch_value
268        if (*struct_defn_ptr == IDL_DT_CS_SHADOW)
269        {
270            struct_defn_ptr++;
271            IDL_GET_LONG_FROM_VECTOR(struct_shadow_length, struct_defn_ptr);
272            struct_cs_shadow = (IDL_cs_shadow_elt_t *)
273                                            rpc_ss_mem_alloc
274                                             (&IDL_msp->IDL_mem_handle,
275                                              struct_shadow_length *
276                                                sizeof(IDL_cs_shadow_elt_t));
277            if (*(array_defn_ptr + 1 + conf_dims * IDL_CONF_BOUND_PAIR_WIDTH)
278                                                             == IDL_DT_CS_TYPE)
279            {
280                /* Conformant array part has [cs_char] base type */
281                rpc_ss_ndr_u_conf_cs_struct_hdr(struct_defn_ptr,
282                                                array_defn_ptr + 1,
283                                                Z_values,
284                                                *struct_offset_vec_ptr,
285                                                *(defn_vec_ptr + 1),
286                                                struct_shadow_length - 1,
287                                                idl_false,
288                                                struct_cs_shadow,
289                                                NULL,
290                                                IDL_msp);
291            }
292        }
293#undef struct_shadow_length
294    }
295
296    if ( (pointer_type == IDL_DT_FULL_PTR)
297         || (*p_pointer == IDL_NEW_NODE) )
298    {
299        /* Calculate storage size for pointee */
300        if (pointee_type == IDL_DT_CONF_STRUCT)
301        {
302            array_defn_ptr++;   /* Was pointing at dimensionality */
303            /* Skip over the bounds in the array defn to get to the base type */
304            /*
305             * Note that correlation checking cannot be performed until the
306             * entire structure is unmarshalled.
307             */
308            IDL_ADV_DEFN_PTR_OVER_BOUNDS( array_defn_ptr, conf_dims );
309
310#define sz_index switch_value
311            if (*array_defn_ptr == IDL_DT_CS_TYPE)
312            {
313                /* There is one [size_is] variable. Get its index in the
314                                                                    cs-shadow */
315                array_defn_ptr -= 4;
316                IDL_GET_LONG_FROM_VECTOR(sz_index, array_defn_ptr);
317                sz_index--;
318                node_size = rpc_ss_ndr_allocation_size( *struct_offset_vec_ptr,
319                                 conf_dims,
320                                 &struct_cs_shadow[sz_index].IDL_data.IDL_value,
321                                 array_defn_ptr, IDL_msp );
322            }
323            else
324#undef sz_index
325                node_size = rpc_ss_ndr_allocation_size( *struct_offset_vec_ptr,
326                                 conf_dims, Z_values, array_defn_ptr, IDL_msp );
327        }
328        else if ( (pointee_type == IDL_DT_VARYING_ARRAY)
329                 || (pointee_type == IDL_DT_CONF_ARRAY)
330                 || (pointee_type == IDL_DT_OPEN_ARRAY) )
331        {
332            /*
333             * The pointer is non-null and the pointee type is a non-fixed
334             * array.  Return if the pointee has already been unmarshalled.
335             */
336            if (pointer_type == IDL_DT_FULL_PTR
337                && p_pointee_desc->already_unmarshalled)
338                return;
339            node_size = rpc_ss_ndr_allocation_size( 0,
340                                            p_pointee_desc->dimensionality,
341                                            p_pointee_desc->Z_values,
342                                            p_pointee_desc->array_base_defn_ptr,
343                                            IDL_msp );
344        }
345        else
346            node_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
347    }
348
349    if (pointer_type == IDL_DT_FULL_PTR)
350    {
351        p_node = (rpc_void_p_t)rpc_ss_return_pointer_to_node(
352                    IDL_msp->IDL_node_table,
353                    node_number, node_size,
354                    (IDL_msp->IDL_side == IDL_client_side_k)
355                        ? &IDL_msp->IDL_allocator : NULL,
356                    &already_unmarshalled,
357                    &new_node );
358        if (p_node == NULL)
359            DCETHREAD_RAISE( rpc_x_no_memory );
360        *p_pointer = p_node;
361        if ( already_unmarshalled )
362            return;
363    }
364    else if (*p_pointer == IDL_NEW_NODE)
365    {
366        rpc_ss_ndr_alloc_storage( node_size, 0, NULL, NULL, &p_node, IDL_msp );
367        *p_pointer = p_node;
368        new_node = idl_true;
369    }
370    else
371    {
372        new_node = idl_false;
373        p_node = *p_pointer;
374    }
375
376    if ( new_node )
377    {
378        /* Fill in any [ref] or [unique] pointers */
379        switch (pointee_type)
380        {
381            case IDL_DT_FIXED_STRUCT:
382                constr_defn_ptr = defn_vec_ptr + 1;    /* Point at properties */
383                if ( IDL_PROP_TEST(*constr_defn_ptr, IDL_PROP_HAS_PTRS) )
384                {
385                    constr_defn_ptr++;
386                    IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,
387                                                            constr_defn_ptr);
388                    struct_defn_ptr = IDL_msp->IDL_type_vec
389                                                         + pointee_defn_index;
390                    rpc_ss_init_new_struct_ptrs( pointee_type, struct_defn_ptr,
391                                             p_node, NULL, IDL_msp );
392                }
393                break;
394            case IDL_DT_CONF_STRUCT:
395                constr_defn_ptr = defn_vec_ptr + 1;    /* Point at properties */
396                if ( IDL_PROP_TEST(*constr_defn_ptr, IDL_PROP_HAS_PTRS) )
397                {
398                    constr_defn_ptr++;
399                    IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,
400                                                            constr_defn_ptr);
401                    struct_defn_ptr = IDL_msp->IDL_type_vec
402                                                         + pointee_defn_index;
403                    rpc_ss_init_new_struct_ptrs( pointee_type, struct_defn_ptr,
404                                             p_node, Z_values, IDL_msp );
405                }
406                break;
407            case IDL_DT_FIXED_ARRAY:
408                constr_defn_ptr = defn_vec_ptr + 1;    /* Point at properties */
409                if ( IDL_PROP_TEST(*constr_defn_ptr, IDL_PROP_HAS_PTRS) )
410                {
411                    constr_defn_ptr++;
412                    IDL_DISCARD_LONG_FROM_VECTOR( constr_defn_ptr );
413                                                    /* Full array definition */
414                    IDL_GET_LONG_FROM_VECTOR( pointee_defn_index,
415                                                             constr_defn_ptr );
416                    rpc_ss_init_new_store_ptrs( pointee_type,
417                                     IDL_msp->IDL_type_vec + pointee_defn_index,
418                                             p_node, NULL, IDL_msp );
419                }
420                break;
421            case IDL_DT_VARYING_ARRAY:
422            case IDL_DT_CONF_ARRAY:
423            case IDL_DT_OPEN_ARRAY:
424                if (p_pointee_desc->base_type_has_pointers)
425                {
426                    rpc_ss_init_new_array_ptrs( p_pointee_desc->dimensionality,
427                                            p_pointee_desc->Z_values,
428                                            p_pointee_desc->array_base_defn_ptr,
429                                            p_node, IDL_msp );
430                }
431                break;
432            case IDL_DT_UNIQUE_PTR:
433                *(rpc_void_p_t *)p_node = IDL_NEW_NODE;
434                break;
435            case IDL_DT_REF_PTR:
436                rpc_ss_alloc_pointer_target( defn_vec_ptr+1, p_node, IDL_msp );
437                break;
438            default:
439                break;
440        }
441    }
442
443    switch(pointee_type)
444    {
445        case IDL_DT_BYTE:
446            IDL_UNMAR_BYTE( p_node );
447            IDL_CHECK_RANGE_BYTE( range_bounds, p_node );
448            break;
449        case IDL_DT_CHAR:
450            IDL_UNMAR_CHAR( p_node );
451            IDL_CHECK_RANGE_CHAR( range_bounds, p_node );
452            break;
453        case IDL_DT_BOOLEAN:
454            IDL_UNMAR_BOOLEAN( p_node );
455            IDL_CHECK_RANGE_BOOLEAN( range_bounds, p_node );
456            break;
457        case IDL_DT_DOUBLE:
458            IDL_UNMAR_DOUBLE( p_node );
459            IDL_CHECK_RANGE_DOUBLE( range_bounds, p_node );
460            break;
461        case IDL_DT_ENUM:
462            IDL_UNMAR_ENUM( p_node );
463            break;
464        case IDL_DT_FLOAT:
465            IDL_UNMAR_FLOAT( p_node );
466            IDL_CHECK_RANGE_FLOAT( range_bounds, p_node );
467            break;
468        case IDL_DT_SMALL:
469            IDL_UNMAR_SMALL( p_node );
470            IDL_CHECK_RANGE_SMALL( range_bounds, p_node );
471            break;
472        case IDL_DT_SHORT:
473            IDL_UNMAR_SHORT( p_node );
474            IDL_CHECK_RANGE_SHORT( range_bounds, p_node );
475            break;
476        case IDL_DT_LONG:
477            IDL_UNMAR_LONG( p_node );
478            IDL_CHECK_RANGE_LONG( range_bounds, p_node );
479            break;
480        case IDL_DT_HYPER:
481            IDL_UNMAR_HYPER( p_node );
482            break;
483        case IDL_DT_USMALL:
484            IDL_UNMAR_USMALL( p_node );
485            IDL_CHECK_RANGE_USMALL( range_bounds, p_node );
486            break;
487        case IDL_DT_USHORT:
488            IDL_UNMAR_USHORT( p_node );
489            IDL_CHECK_RANGE_USHORT( range_bounds, p_node );
490            break;
491        case IDL_DT_ULONG:
492            IDL_UNMAR_ULONG( p_node );
493            IDL_CHECK_RANGE_ULONG( range_bounds, p_node );
494            break;
495        case IDL_DT_UHYPER:
496            IDL_UNMAR_UHYPER( p_node );
497            break;
498        case IDL_DT_ERROR_STATUS:
499            IDL_UNMAR_ERROR_STATUS( p_node );
500            break;
501        case IDL_DT_FIXED_STRUCT:
502        case IDL_DT_CONF_STRUCT:
503            /* Properties byte */
504            defn_vec_ptr++;
505            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
506            defn_vec_ptr++;
507            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
508            rpc_ss_ndr_unmar_struct(pointee_type,
509                                   IDL_msp->IDL_type_vec+pointee_defn_index,
510                                   p_node, Z_values,
511						struct_cs_shadow,
512								IDL_msp);
513            if (type_has_pointers)
514            {
515                rpc_ss_ndr_u_struct_pointees( pointee_type, pointee_defn_index,
516                                                p_node, Z_values, IDL_msp );
517            }
518            if (pointee_type == IDL_DT_CONF_STRUCT)
519                rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
520                                        (byte_p_t)Z_values);
521            break;
522        case IDL_DT_FIXED_ARRAY:
523            /* Properties byte */
524            defn_vec_ptr++;
525            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
526            defn_vec_ptr++;
527            IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
528                                                    /* Full array definition */
529            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index, defn_vec_ptr);
530            rpc_ss_ndr_unmar_fixed_arr( pointee_defn_index, p_node,
531                                        0, IDL_msp );
532            if (type_has_pointers)
533            {
534                rpc_ss_ndr_u_fixed_arr_ptees( pointee_defn_index, p_node,
535                                                                     IDL_msp );
536            }
537            break;
538        case IDL_DT_VARYING_ARRAY:
539        case IDL_DT_OPEN_ARRAY:
540            rpc_ss_ndr_u_var_or_open_arr( p_pointee_desc->dimensionality,
541                                          p_pointee_desc->Z_values,
542                                          p_pointee_desc->array_base_defn_ptr,
543                                          p_node,
544                                          p_pointee_desc->range_list,
545                                          0, IDL_msp );
546            if (p_pointee_desc->base_type_has_pointers)
547            {
548                rpc_ss_ndr_u_v_or_o_arr_ptees( p_pointee_desc->dimensionality,
549                                          p_pointee_desc->Z_values,
550                                          p_pointee_desc->array_base_defn_ptr,
551                                          p_node,
552                                          p_pointee_desc->range_list, IDL_msp );
553            }
554            break;
555        case IDL_DT_CONF_ARRAY:
556            rpc_ss_ndr_u_fix_or_conf_arr( p_pointee_desc->dimensionality,
557                                          p_pointee_desc->Z_values,
558                                          p_pointee_desc->array_base_defn_ptr,
559                                          p_node, IDL_M_CONF_ARRAY, IDL_msp );
560            if (p_pointee_desc->base_type_has_pointers)
561            {
562                rpc_ss_ndr_u_f_or_c_arr_ptees( p_pointee_desc->dimensionality,
563                                          p_pointee_desc->Z_values,
564                                          p_pointee_desc->array_base_defn_ptr,
565                                          p_node, IDL_msp );
566            }
567            break;
568        case IDL_DT_ENC_UNION:
569            /* Properties byte */
570            defn_vec_ptr++;
571            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
572            defn_vec_ptr++;
573            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index, defn_vec_ptr);
574            rpc_ss_ndr_u_enc_union_or_ptees(p_node, pointee_defn_index,
575                                            idl_false, IDL_msp);
576            if (type_has_pointers)
577            {
578                rpc_ss_ndr_u_enc_union_or_ptees(p_node,
579                                        pointee_defn_index, idl_true, IDL_msp);
580            }
581            break;
582        case IDL_DT_N_E_UNION:
583            /* Properties byte */
584            defn_vec_ptr++;
585            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
586            defn_vec_ptr++;
587            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Switch index */
588            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
589            rpc_ss_ndr_unmar_n_e_union(p_node, pointee_defn_index,
590                                       &switch_value, IDL_msp);
591            if (type_has_pointers)
592            {
593                rpc_ss_ndr_u_n_e_union_ptees(p_node, switch_value, 0,
594                                       pointee_defn_index, NULL, NULL, IDL_msp);
595            }
596            break;
597        case IDL_DT_FULL_PTR:
598        case IDL_DT_UNIQUE_PTR:
599        case IDL_DT_REF_PTR:
600            rpc_ss_ndr_unmar_ptr_ptee(pointee_type, p_node, defn_vec_ptr,
601                                                                     IDL_msp);
602            break;
603        case IDL_DT_TRANSMIT_AS:
604        case IDL_DT_REPRESENT_AS:
605            defn_vec_ptr += 2;      /* Byte after properties byte */
606            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index, defn_vec_ptr);
607            rpc_ss_ndr_unmar_xmit_as(pointee_defn_index, p_node, NULL, IDL_msp);
608            break;
609#if 0
610        case IDL_DT_INTERFACE:
611            defn_vec_ptr++;     /* Properties byte */
612            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index, defn_vec_ptr);
613            rpc_ss_ndr_unmar_interface(pointee_defn_index,p_node,NULL,IDL_msp);
614            break;
615#endif
616
617        case IDL_DT_CS_ARRAY:
618            defn_vec_ptr++;     /* Move to IDL_DT_FIXED_ARRAY */
619            rpc_ss_ndr_unmar_cs_array(p_node, NULL, NULL, 0, &defn_vec_ptr,
620                                                                       IDL_msp);
621            break;
622        case IDL_DT_CS_TYPE:
623            defn_vec_ptr += 2;      /* Byte after properties byte */
624            IDL_GET_LONG_FROM_VECTOR(pointee_defn_index, defn_vec_ptr);
625            rpc_ss_ndr_unmar_cs_char(p_node, pointee_defn_index, IDL_msp);
626            break;
627        default:
628#ifdef DEBUG_INTERP
629             printf("rpc_ss_ndr_unmar_pointee:unrecognized type %d\n",
630                        pointee_type);
631             exit(0);
632#endif
633             DCETHREAD_RAISE(rpc_x_coding_error);
634    }
635}
636
637/******************************************************************************/
638/*                                                                            */
639/*  Unmarshall a structure's pointees                                         */
640/*                                                                            */
641/******************************************************************************/
642void rpc_ss_ndr_u_struct_pointees
643(
644    /* [in] */  idl_byte struct_type,   /* DT_FIXED_STRUCT or DT_CONF_STRUCT */
645    /* [in] */  idl_ulong_int defn_index,   /* Index of structure description */
646    /* [in] */  rpc_void_p_t struct_addr,
647    /* [in] */  idl_ulong_int *Z_values,    /* If conformant structure, the
648                 Z values for the conformant or open field, otherwise ignored */
649    IDL_msp_t IDL_msp
650)
651{
652    idl_ulong_int offset_index;
653    idl_byte *defn_vec_ptr;
654    idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */
655    idl_ulong_int *offset_vec_ptr;
656    idl_byte type_byte;
657    idl_ulong_int offset;
658    idl_ulong_int field_defn_index;
659    idl_byte *field_defn_ptr;
660    idl_boolean type_has_pointers;
661    IDL_bound_pair_t *bounds_list;
662    idl_ulong_int *varying_Z_values;    /* Z_values for a varying array field */
663    IDL_bound_pair_t *range_list;
664    idl_ulong_int array_dims;    /* Number of dimensions of array */
665    IDL_pointee_desc_t pointee_desc;    /* Description of pointee */
666    idl_ulong_int switch_index; /* Index of switch field for non-encapsulated
667                                                                        union */
668    idl_boolean add_null;       /* Dummy argument in procedure call */
669
670    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
671    IDL_GET_LONG_FROM_VECTOR(offset_index,defn_vec_ptr);
672    struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index;
673
674    if (struct_type == IDL_DT_CONF_STRUCT)
675    {
676        IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
677    }
678
679    offset_vec_ptr = struct_offset_vec_ptr + 1;
680                                        /* Skip over size at start of offsets */
681    pointee_desc.dimensionality = 0;
682    /* necessary for correlation checking */
683    pointee_desc.struct_addr = struct_addr;
684    pointee_desc.struct_offset_vec_ptr = struct_offset_vec_ptr;
685
686    /* Loop over the fields of the structure */
687    do {
688        type_byte = *defn_vec_ptr;
689        defn_vec_ptr++;
690        switch(type_byte)
691        {
692            /* For fields that do not include pointers, just advance the
693                definition and offset pointers in step */
694            case IDL_DT_CS_SHADOW:
695                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
696                break;
697            case IDL_DT_BYTE:
698            case IDL_DT_CHAR:
699            case IDL_DT_BOOLEAN:
700            case IDL_DT_DOUBLE:
701            case IDL_DT_ENUM:
702            case IDL_DT_FLOAT:
703            case IDL_DT_SMALL:
704            case IDL_DT_SHORT:
705            case IDL_DT_LONG:
706            case IDL_DT_HYPER:
707            case IDL_DT_USMALL:
708            case IDL_DT_USHORT:
709            case IDL_DT_ULONG:
710            case IDL_DT_UHYPER:
711            case IDL_DT_IGNORE:
712            case IDL_DT_V1_ENUM:
713            case IDL_DT_ERROR_STATUS:
714                offset_vec_ptr++;
715                break;
716            case IDL_DT_FIXED_ARRAY:
717                /* Properties byte */
718                type_has_pointers =
719                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
720                defn_vec_ptr++;
721                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
722                                                    /* Full array definition */
723                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
724                if (type_has_pointers)
725                {
726                    offset = *offset_vec_ptr;
727                    rpc_ss_ndr_u_fixed_arr_ptees( field_defn_index,
728                                      (idl_byte *)struct_addr+offset, IDL_msp);
729                }
730                offset_vec_ptr++;
731                break;
732            case IDL_DT_VARYING_ARRAY:
733                /* Properties byte */
734                type_has_pointers =
735                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
736                defn_vec_ptr++;
737                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
738                                                    /* Full array definition */
739                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
740                if (type_has_pointers)
741                {
742                    offset = *offset_vec_ptr;
743                    field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
744                    array_dims = (idl_ulong_int)*field_defn_ptr;
745                    field_defn_ptr++;
746		    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
747			rpc_ss_fixed_bounds_from_vector(array_dims,
748							field_defn_ptr,
749							&bounds_list, IDL_msp);
750		    else
751		      bounds_list = (IDL_bound_pair_t *)field_defn_ptr;
752                    varying_Z_values = NULL;
753                    rpc_ss_Z_values_from_bounds( bounds_list, array_dims,
754                                                 &varying_Z_values, IDL_msp );
755                    /* Advance definition pointer over bounds */
756                    field_defn_ptr += array_dims * IDL_FIXED_BOUND_PAIR_WIDTH;
757                    range_list = NULL;
758                    rpc_ss_build_range_list(&field_defn_ptr,
759                                (rpc_void_p_t)((idl_byte *)struct_addr+offset),
760                                struct_addr, struct_offset_vec_ptr, array_dims,
761                                bounds_list, &range_list, &add_null, IDL_msp);
762                    rpc_ss_ndr_u_v_or_o_arr_ptees( array_dims, varying_Z_values,
763                            field_defn_ptr,
764                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
765                            range_list, IDL_msp );
766                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
767                                            (byte_p_t)range_list);
768                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
769                                            (byte_p_t)varying_Z_values);
770		    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
771		      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
772                                            (byte_p_t)bounds_list);
773                }
774                offset_vec_ptr++;
775                break;
776            case IDL_DT_CONF_ARRAY:
777                /* Properties byte */
778                type_has_pointers =
779                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
780                defn_vec_ptr++;
781                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
782                                                    /* Full array definition */
783                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
784                if (type_has_pointers)
785                {
786                    /* Conformant array must be last field of struct */
787                    offset = *offset_vec_ptr;
788                    field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
789                    array_dims = (idl_ulong_int)*field_defn_ptr;
790                    field_defn_ptr++;   /* Now at (0 mod 4) */
791                    rpc_ss_ndr_unmar_check_bounds_correlation( &field_defn_ptr,
792                                             (idl_byte *)struct_addr + offset,
793                                             struct_addr,
794                                             struct_offset_vec_ptr,
795                                             array_dims,
796                                             Z_values,
797                                             FALSE,
798                                             NULL,
799                                             IDL_msp );
800
801                    rpc_ss_ndr_u_f_or_c_arr_ptees( array_dims, Z_values,
802                             field_defn_ptr, (idl_byte *)struct_addr+offset,
803                             IDL_msp );
804                }
805                break;
806            case IDL_DT_OPEN_ARRAY:
807                /* Properties byte */
808                type_has_pointers =
809                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
810                defn_vec_ptr++;
811                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
812                                                    /* Full array definition */
813                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
814                if (type_has_pointers)
815                {
816                    /* Open array must be last field of struct */
817                    offset = *offset_vec_ptr;
818                    field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
819                    array_dims = (idl_ulong_int)*field_defn_ptr;
820                    field_defn_ptr++;   /* Now at (0 mod 4) */
821                    bounds_list = NULL;
822                    rpc_ss_build_bounds_list(&field_defn_ptr,
823                                (rpc_void_p_t)((idl_byte *)struct_addr+offset),
824                                struct_addr, struct_offset_vec_ptr, array_dims,
825                                            &bounds_list, IDL_msp);
826                    range_list = NULL;
827                    rpc_ss_build_range_list(&field_defn_ptr,
828                                (rpc_void_p_t)((idl_byte *)struct_addr+offset),
829                                struct_addr, struct_offset_vec_ptr, array_dims,
830                                bounds_list, &range_list, &add_null, IDL_msp);
831                    rpc_ss_ndr_u_v_or_o_arr_ptees( array_dims, Z_values,
832                         field_defn_ptr, (idl_byte *)struct_addr+offset,
833                         range_list, IDL_msp );
834                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
835                                            (byte_p_t)range_list);
836                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
837                                            (byte_p_t)bounds_list);
838                }
839                break;
840            case IDL_DT_ENC_UNION:
841                /* Properties byte */
842                type_has_pointers =
843                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
844                defn_vec_ptr++;
845                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
846                if (type_has_pointers)
847                {
848                    offset = *offset_vec_ptr;
849                    rpc_ss_ndr_u_enc_union_or_ptees(
850                                              (idl_byte *)struct_addr+offset,
851                                           field_defn_index, idl_true, IDL_msp);
852                }
853                offset_vec_ptr++;
854                break;
855            case IDL_DT_N_E_UNION:
856                /* Properties byte */
857                type_has_pointers =
858                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
859                defn_vec_ptr++;
860                IDL_GET_LONG_FROM_VECTOR(switch_index, defn_vec_ptr);
861                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
862                if (type_has_pointers)
863                {
864                    offset = *offset_vec_ptr;
865                    rpc_ss_ndr_u_n_e_union_ptees(
866                                    (idl_byte *)struct_addr+offset, 0,
867                                    switch_index, field_defn_index, struct_addr,
868                                    struct_offset_vec_ptr, IDL_msp);
869                }
870                offset_vec_ptr++;
871                break;
872            case IDL_DT_FULL_PTR:
873                defn_vec_ptr++;     /* Properties byte */
874                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
875                offset = *offset_vec_ptr;
876                offset_vec_ptr++;
877                if (*(rpc_void_p_t *)((idl_byte *)struct_addr + offset)
878                                                                     != NULL)
879                {
880                    field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
881                    rpc_ss_ndr_unmar_pointee_desc( type_byte,
882                            field_defn_ptr, &pointee_desc,
883                            (rpc_void_p_t *)((idl_byte *)struct_addr + offset),
884                            IDL_msp );
885                    rpc_ss_ndr_unmar_pointee( type_byte,
886                            field_defn_ptr, &pointee_desc,
887                            (rpc_void_p_t *)((idl_byte *)struct_addr + offset),
888                            IDL_msp );
889                }
890                break;
891            case IDL_DT_UNIQUE_PTR:
892                defn_vec_ptr++;     /* Properties byte */
893                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
894                offset = *offset_vec_ptr;
895                offset_vec_ptr++;
896                if (*(rpc_void_p_t *)((idl_byte *)struct_addr + offset)
897                                                                     != NULL)
898                {
899                    field_defn_ptr = IDL_msp->IDL_type_vec
900                                                    + field_defn_index;
901                    rpc_ss_ndr_unmar_pointee_desc( type_byte, field_defn_ptr,
902                            &pointee_desc,
903                            (rpc_void_p_t *)((idl_byte *)struct_addr + offset),
904                            IDL_msp );
905                    rpc_ss_ndr_unmar_pointee( type_byte, field_defn_ptr,
906                            &pointee_desc,
907                            (rpc_void_p_t *)((idl_byte *)struct_addr + offset),
908                            IDL_msp );
909                }
910                break;
911            case IDL_DT_REF_PTR:
912                defn_vec_ptr++;     /* Properties byte */
913                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
914                field_defn_ptr = IDL_msp->IDL_type_vec+field_defn_index;
915                offset = *offset_vec_ptr;
916                offset_vec_ptr++;
917                rpc_ss_ndr_unmar_pointee_desc( type_byte, field_defn_ptr,
918                        &pointee_desc,
919                        (rpc_void_p_t *)((idl_byte *)struct_addr + offset),
920                        IDL_msp );
921                if ( (pointee_desc.pointee_type == IDL_DT_CONF_STRUCT)
922                    || (pointee_desc.pointee_type == IDL_DT_STRING)
923                    || (pointee_desc.pointee_type == IDL_DT_CONF_ARRAY)
924                    || (pointee_desc.pointee_type == IDL_DT_OPEN_ARRAY) )
925                {
926                    *((rpc_void_p_t *)((idl_byte *)struct_addr + offset)) = IDL_NEW_NODE;
927                }
928                rpc_ss_ndr_unmar_pointee( type_byte, field_defn_ptr,
929                        &pointee_desc,
930                        (rpc_void_p_t *)((idl_byte *)struct_addr + offset),
931                        IDL_msp );
932                break;
933            case IDL_DT_TRANSMIT_AS:
934            case IDL_DT_REPRESENT_AS:
935            case IDL_DT_CS_TYPE:
936                defn_vec_ptr++;     /* Properties byte */
937                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
938                offset_vec_ptr++;
939                break;
940            case IDL_DT_RANGE:
941                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
942                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
943                break;
944            case IDL_DT_STRING:
945            case IDL_DT_NDR_ALIGN_2:
946            case IDL_DT_NDR_ALIGN_4:
947            case IDL_DT_NDR_ALIGN_8:
948            case IDL_DT_BEGIN_NESTED_STRUCT:
949            case IDL_DT_END_NESTED_STRUCT:
950            case IDL_DT_V1_ARRAY:
951            case IDL_DT_V1_STRING:
952            case IDL_DT_CS_ATTRIBUTE:
953            case IDL_DT_CS_ARRAY:
954            case IDL_DT_CS_RLSE_SHADOW:
955            case IDL_DT_EOL:
956                break;
957            default:
958#ifdef DEBUG_INTERP
959                printf("rpc_ss_ndr_u_struct_pointees:unrecognized type %d\n",
960                        type_byte);
961                exit(0);
962#endif
963                DCETHREAD_RAISE(rpc_x_coding_error);
964        }
965    } while (type_byte != IDL_DT_EOL);
966
967    rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp );
968}
969
970/******************************************************************************/
971/*                                                                            */
972/* Unmarshall the pointees of a fixed or conformant array                     */
973/*                                                                            */
974/******************************************************************************/
975void rpc_ss_ndr_u_f_or_c_arr_ptees
976(
977    /* [in] */  idl_ulong_int dimensionality,
978    /* [in] */  idl_ulong_int *Z_values,
979    /* [in] */  idl_byte *defn_vec_ptr, /* On entry points at array base info */
980    /* [in] */  rpc_void_p_t array_addr,
981    IDL_msp_t IDL_msp
982)
983{
984    idl_ulong_int element_count;
985    unsigned32 i;
986    idl_byte base_type;
987    idl_ulong_int element_size;
988    idl_ulong_int element_defn_index;
989    idl_ulong_int element_offset_index;
990    idl_byte *element_defn_ptr;
991    rpc_void_p_t *array_elt_addr;
992    IDL_pointee_desc_t pointee_desc;
993
994    element_count = 1;
995    for (i=0; i<dimensionality; i++)
996    {
997        element_count *= Z_values[i];
998    }
999
1000    base_type = *defn_vec_ptr;
1001
1002    if (base_type == IDL_DT_FIXED_STRUCT)
1003    {
1004        defn_vec_ptr += 2;  /* DT_FIXED_STRUCT and properties byte */
1005        /* Array of structures containing pointers */
1006        IDL_GET_LONG_FROM_VECTOR(element_defn_index, defn_vec_ptr);
1007        element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index;
1008        IDL_GET_LONG_FROM_VECTOR(element_offset_index, element_defn_ptr);
1009        element_size = *(IDL_msp->IDL_offset_vec + element_offset_index);
1010        for (i=0; i<element_count; i++)
1011        {
1012            rpc_ss_ndr_u_struct_pointees( base_type, element_defn_index,
1013                                            array_addr, NULL, IDL_msp );
1014            array_addr = (rpc_void_p_t)((idl_byte *)array_addr + element_size);
1015        }
1016    }
1017    else if (base_type == IDL_DT_ENC_UNION)
1018    {
1019        defn_vec_ptr += 2;  /* DT_ENC_UNION and properties byte */
1020        /* Array of unions containing pointers */
1021        IDL_GET_LONG_FROM_VECTOR(element_defn_index, defn_vec_ptr);
1022        element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index;
1023        IDL_GET_LONG_FROM_VECTOR(element_offset_index, element_defn_ptr);
1024        element_size = *(IDL_msp->IDL_offset_vec + element_offset_index);
1025        for (i=0; i<element_count; i++)
1026        {
1027            rpc_ss_ndr_u_enc_union_or_ptees( array_addr, element_defn_index,
1028                                             idl_true, IDL_msp );
1029            array_addr = (rpc_void_p_t)((idl_byte *)array_addr + element_size);
1030        }
1031    }
1032    else
1033    {
1034        defn_vec_ptr++;     /* Move to pointee type */
1035        /* Array of pointers */
1036        array_elt_addr = (rpc_void_p_t *)(array_addr);
1037        pointee_desc.dimensionality = 0;
1038        pointee_desc.struct_addr = NULL;
1039        pointee_desc.struct_offset_vec_ptr = NULL;
1040        for (i=0; i<element_count; i++)
1041        {
1042            rpc_ss_ndr_unmar_pointee_desc( base_type, defn_vec_ptr,
1043                          &pointee_desc, array_elt_addr, IDL_msp );
1044            rpc_ss_ndr_unmar_pointee( base_type, defn_vec_ptr, &pointee_desc,
1045                                         array_elt_addr, IDL_msp );
1046            array_elt_addr++;
1047        }
1048        rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp );
1049    }
1050}
1051
1052/******************************************************************************/
1053/*                                                                            */
1054/*  Unmarshall the pointees of a fixed array                                  */
1055/*                                                                            */
1056/******************************************************************************/
1057void rpc_ss_ndr_u_fixed_arr_ptees
1058(
1059    /* [in] */  idl_ulong_int defn_index,   /* Index of array description */
1060    /* [in] */  rpc_void_p_t array_addr,
1061    IDL_msp_t IDL_msp
1062)
1063{
1064    idl_byte *defn_vec_ptr;
1065    idl_ulong_int dimensionality;
1066    idl_ulong_int *Z_values;
1067    IDL_bound_pair_t *bounds_list;
1068
1069    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
1070    dimensionality = (idl_ulong_int)*defn_vec_ptr;
1071    defn_vec_ptr++;     /* By design alignment is now (0 mod 4) */
1072    Z_values = NULL;
1073    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1074      rpc_ss_fixed_bounds_from_vector(dimensionality, defn_vec_ptr, &bounds_list,
1075				      IDL_msp);
1076    else
1077      bounds_list = (IDL_bound_pair_t *)defn_vec_ptr;
1078    rpc_ss_Z_values_from_bounds( bounds_list,
1079                                     dimensionality, &Z_values, IDL_msp );
1080    defn_vec_ptr += dimensionality * IDL_FIXED_BOUND_PAIR_WIDTH;
1081    rpc_ss_ndr_u_f_or_c_arr_ptees( dimensionality, Z_values, defn_vec_ptr,
1082                                     array_addr, IDL_msp);
1083    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1084    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1085      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1086}
1087
1088/******************************************************************************/
1089/*                                                                            */
1090/*  Unmarshall the pointees of a varying or open array                        */
1091/*                                                                            */
1092/******************************************************************************/
1093void rpc_ss_ndr_u_v_or_o_arr_ptees
1094(
1095    /* [in] */  idl_ulong_int dimensionality,
1096    /* [in] */  idl_ulong_int *Z_values,
1097    /* [in] */  idl_byte *defn_vec_ptr, /* On entry points to array base info */
1098    /* [in] */  rpc_void_p_t array_addr,
1099    /* [in] */  IDL_bound_pair_t *range_list,
1100    IDL_msp_t IDL_msp
1101)
1102{
1103    idl_byte base_type;
1104    idl_ulong_int element_defn_index;
1105    idl_ulong_int element_size;
1106    idl_byte *element_defn_ptr;
1107    idl_ulong_int element_offset_index;
1108    IDL_varying_control_t *control_data;
1109    int i;
1110    idl_byte *inner_slice_address;  /* Address of 1-dim subset of array */
1111    int dim;    /* Index through array dimensions */
1112    IDL_pointee_desc_t pointee_desc;
1113
1114    base_type = *defn_vec_ptr;
1115
1116    element_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
1117    defn_vec_ptr++;
1118
1119    if ( (base_type == IDL_DT_FIXED_STRUCT) || (base_type == IDL_DT_ENC_UNION) )
1120    {
1121        IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1122        element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index;
1123        IDL_GET_LONG_FROM_VECTOR(element_offset_index, element_defn_ptr);
1124        element_size = *(IDL_msp->IDL_offset_vec + element_offset_index);
1125    }
1126
1127    control_data = (IDL_varying_control_t *)rpc_ss_mem_alloc(
1128                                &IDL_msp->IDL_mem_handle,
1129                                dimensionality * sizeof(IDL_varying_control_t));
1130    control_data[dimensionality-1].subslice_size = element_size;
1131    control_data[dimensionality-1].index_value =
1132                                            range_list[dimensionality-1].lower;
1133    for (i=dimensionality-2; i>=0; i--)
1134    {
1135        control_data[i].index_value = range_list[i].lower;
1136        control_data[i].subslice_size = control_data[i+1].subslice_size
1137                                                            * Z_values[i+1];
1138    }
1139
1140    pointee_desc.dimensionality = 0;
1141    pointee_desc.struct_addr = NULL;
1142    pointee_desc.struct_offset_vec_ptr = NULL;
1143    do {
1144        inner_slice_address = (idl_byte *)array_addr;
1145        for (i = 0; (unsigned) i < dimensionality; i++)
1146        {
1147            inner_slice_address += control_data[i].index_value
1148                                        * control_data[i].subslice_size;
1149        }
1150        for (i = range_list[dimensionality-1].lower;
1151             i < range_list[dimensionality-1].upper;
1152             i++)
1153        {
1154            if (base_type == IDL_DT_FIXED_STRUCT)
1155            {
1156                rpc_ss_ndr_u_struct_pointees(base_type, element_defn_index,
1157                                            inner_slice_address, NULL, IDL_msp);
1158                inner_slice_address += element_size;
1159            }
1160            else if (base_type == IDL_DT_ENC_UNION)
1161            {
1162                rpc_ss_ndr_u_enc_union_or_ptees(inner_slice_address,
1163                                                element_defn_index,
1164                                                idl_true, IDL_msp);
1165                inner_slice_address += element_size;
1166            }
1167            else
1168            {
1169                rpc_ss_ndr_unmar_pointee_desc(base_type, defn_vec_ptr,
1170                                          &pointee_desc,
1171                                          (rpc_void_p_t *)inner_slice_address,
1172                                                                      IDL_msp);
1173                rpc_ss_ndr_unmar_pointee(base_type, defn_vec_ptr, &pointee_desc,
1174                                          (rpc_void_p_t *)inner_slice_address,
1175                                                                      IDL_msp);
1176                inner_slice_address += sizeof(rpc_void_p_t *);
1177            }
1178        }
1179        dim = dimensionality - 2;
1180        while (dim >= 0)
1181        {
1182            control_data[dim].index_value++;
1183            if (control_data[dim].index_value < (unsigned32)range_list[dim].upper)
1184                break;
1185            control_data[dim].index_value = range_list[dim].lower;
1186            dim--;
1187        }
1188    } while (dim >= 0);
1189
1190    rpc_ss_ndr_u_rlse_pointee_desc(&pointee_desc, IDL_msp);
1191    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)control_data);
1192}
1193
1194/******************************************************************************/
1195/*                                                                            */
1196/*  Allocate the target of a [ref] pointer                                    */
1197/*                                                                            */
1198/******************************************************************************/
1199void rpc_ss_alloc_pointer_target
1200(
1201    /* [in] */ idl_byte *defn_vec_ptr,  /* On entry points at pointee type */
1202    /* [out] */ rpc_void_p_t *p_pointer,
1203                      /* Exit - points to the address of the pointee */
1204    IDL_msp_t IDL_msp
1205)
1206{
1207    idl_ulong_int node_size;
1208    idl_byte pointee_type;
1209    idl_boolean type_has_pointers;
1210    idl_ulong_int pointee_defn_index;
1211
1212    pointee_type = *defn_vec_ptr;
1213    if ( (pointee_type == IDL_DT_CONF_STRUCT)
1214        || (pointee_type == IDL_DT_STRING)
1215        || (pointee_type == IDL_DT_CONF_ARRAY)
1216        || (pointee_type == IDL_DT_OPEN_ARRAY) )
1217    {
1218        *p_pointer = IDL_NEW_NODE;  /* Must allocate when Z-values available */
1219        return;
1220    }
1221    else
1222        node_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
1223
1224    rpc_ss_ndr_alloc_storage( node_size, 0, NULL, NULL, p_pointer, IDL_msp );
1225
1226    switch(pointee_type)
1227    {
1228        case IDL_DT_BYTE:
1229        case IDL_DT_CHAR:
1230        case IDL_DT_BOOLEAN:
1231        case IDL_DT_DOUBLE:
1232        case IDL_DT_ENUM:
1233        case IDL_DT_FLOAT:
1234        case IDL_DT_SMALL:
1235        case IDL_DT_SHORT:
1236        case IDL_DT_LONG:
1237        case IDL_DT_HYPER:
1238        case IDL_DT_USMALL:
1239        case IDL_DT_USHORT:
1240        case IDL_DT_ULONG:
1241        case IDL_DT_UHYPER:
1242        case IDL_DT_V1_ENUM:
1243        case IDL_DT_ERROR_STATUS:
1244            break;
1245#if 0
1246/* We might no longer need this case due to other fixes,
1247   but I'm keeping it around just in case
1248
1249   -- Brian
1250*/
1251        case IDL_DT_N_E_UNION:
1252            /* Properties byte */
1253            defn_vec_ptr++;
1254            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
1255            if (type_has_pointers)
1256            {
1257                defn_vec_ptr++;
1258                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Switch index */
1259                IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
1260                /* FIXME: figure out how to correctly initialize the union */
1261/*                rpc_ss_init_new_store_ptrs(pointee_type,
1262                                           IDL_msp->IDL_type_vec+pointee_defn_index,
1263                                           *p_pointer, NULL,
1264                                           IDL_msp);*/
1265            }
1266            break;
1267#endif
1268        case IDL_DT_FIXED_STRUCT:
1269        case IDL_DT_FIXED_ARRAY:
1270            /* Properties byte */
1271            defn_vec_ptr++;
1272            type_has_pointers = IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
1273            if (type_has_pointers)
1274            {
1275                defn_vec_ptr++;
1276                IDL_GET_LONG_FROM_VECTOR(pointee_defn_index,defn_vec_ptr);
1277                rpc_ss_init_new_store_ptrs(pointee_type,
1278                                       IDL_msp->IDL_type_vec+pointee_defn_index,
1279                                       *p_pointer, NULL,
1280                                       IDL_msp);
1281            }
1282            break;
1283        case IDL_DT_ENC_UNION:
1284        case IDL_DT_FULL_PTR:
1285        case IDL_DT_TRANSMIT_AS:
1286        case IDL_DT_REPRESENT_AS:
1287        case IDL_DT_CS_TYPE:
1288        case IDL_DT_CS_ARRAY:
1289        case IDL_DT_RANGE:
1290            break;
1291        case IDL_DT_UNIQUE_PTR:
1292        case IDL_DT_REF_PTR:
1293            rpc_ss_init_new_store_ptrs(pointee_type,
1294                                       defn_vec_ptr+1,
1295                                       *p_pointer, NULL,
1296                                       IDL_msp);
1297            break;
1298        default:
1299#ifdef DEBUG_INTERP
1300             printf("rpc_ss_alloc_pointer_target:unrecognized type %d\n",
1301                        pointee_type);
1302             exit(0);
1303#endif
1304             DCETHREAD_RAISE(rpc_x_coding_error);
1305    }
1306}
1307
1308/******************************************************************************/
1309/*                                                                            */
1310/*  Initialize the [ref] and [unique] pointers in structure not allocated by  */
1311/*      the application                                                       */
1312/*                                                                            */
1313/******************************************************************************/
1314void rpc_ss_init_new_struct_ptrs
1315(
1316    /* [in] */  idl_byte struct_type,   /* DT_FIXED_STRUCT or DT_CONF_STRUCT */
1317    /* [in] */  idl_byte *defn_vec_ptr, /* Points at structure definition */
1318    /* [in] */  rpc_void_p_t struct_addr,
1319    /* [in] */  idl_ulong_int *conf_Z_values,   /* If conformant structure, the
1320                 Z values for the conformant or open field, otherwise ignored */
1321    IDL_msp_t IDL_msp
1322)
1323{
1324    idl_ulong_int offset_index;
1325    idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */
1326    idl_ulong_int *offset_vec_ptr;
1327    idl_byte type_byte;
1328    idl_ulong_int offset;
1329    idl_ulong_int array_defn_index;
1330    idl_byte *array_defn_ptr;
1331    idl_boolean type_has_pointers;
1332    idl_ulong_int pointee_defn_index;
1333    IDL_bound_pair_t *bounds_list;
1334    idl_ulong_int *Z_values;
1335    idl_ulong_int array_dims;    /* Number of dimensions of array */
1336
1337    IDL_GET_LONG_FROM_VECTOR(offset_index,defn_vec_ptr);
1338    struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index;
1339
1340    if (struct_type == IDL_DT_CONF_STRUCT)
1341    {
1342        IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
1343    }
1344
1345    offset_vec_ptr = struct_offset_vec_ptr + 1;
1346                                        /* Skip over size at start of offsets */
1347    /* Loop over the fields of the structure */
1348    do {
1349        type_byte = *defn_vec_ptr;
1350        defn_vec_ptr++;
1351        switch(type_byte)
1352        {
1353            /* For fields that do not include pointers, just advance the
1354                definition and offset pointers in step */
1355            case IDL_DT_BYTE:
1356            case IDL_DT_CHAR:
1357            case IDL_DT_BOOLEAN:
1358            case IDL_DT_DOUBLE:
1359            case IDL_DT_ENUM:
1360            case IDL_DT_FLOAT:
1361            case IDL_DT_SMALL:
1362            case IDL_DT_SHORT:
1363            case IDL_DT_LONG:
1364            case IDL_DT_HYPER:
1365            case IDL_DT_USMALL:
1366            case IDL_DT_USHORT:
1367            case IDL_DT_ULONG:
1368            case IDL_DT_UHYPER:
1369            case IDL_DT_IGNORE:
1370            case IDL_DT_V1_ENUM:
1371            case IDL_DT_ERROR_STATUS:
1372                offset_vec_ptr++;
1373                break;
1374            case IDL_DT_FIXED_ARRAY:
1375                /* Properties byte */
1376                type_has_pointers =
1377                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
1378                defn_vec_ptr++;
1379                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
1380                                                    /* Full array definition */
1381                IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
1382                if (type_has_pointers)
1383                {
1384                    offset = *offset_vec_ptr;
1385                    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1386                    array_dims = (idl_ulong_int)*array_defn_ptr;
1387                    array_defn_ptr++;
1388		    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1389			rpc_ss_fixed_bounds_from_vector(array_dims,
1390							array_defn_ptr,
1391							&bounds_list, IDL_msp);
1392		    else
1393		      bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
1394                    Z_values = NULL;
1395                    rpc_ss_Z_values_from_bounds( bounds_list, array_dims,
1396                                                 &Z_values, IDL_msp );
1397                    /* Advance definition pointer over bounds */
1398                    array_defn_ptr += array_dims * IDL_FIXED_BOUND_PAIR_WIDTH;
1399                    rpc_ss_init_new_array_ptrs( array_dims, Z_values,
1400                            array_defn_ptr,
1401                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
1402                            IDL_msp );
1403                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1404                                            (byte_p_t)Z_values);
1405		    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1406		      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1407					   (byte_p_t)bounds_list);
1408                }
1409                offset_vec_ptr++;
1410                break;
1411            case IDL_DT_VARYING_ARRAY:
1412                /* Properties byte */
1413                type_has_pointers =
1414                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
1415                defn_vec_ptr++;
1416                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
1417                                                    /* Full array definition */
1418                IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
1419                if (type_has_pointers)
1420                {
1421                    offset = *offset_vec_ptr;
1422                    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1423                    array_dims = (idl_ulong_int)*array_defn_ptr;
1424                    array_defn_ptr++;
1425		    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1426			rpc_ss_fixed_bounds_from_vector(array_dims,
1427							array_defn_ptr,
1428							&bounds_list, IDL_msp);
1429		    else
1430		      bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
1431                    Z_values = NULL;
1432                    rpc_ss_Z_values_from_bounds( bounds_list, array_dims,
1433                                                 &Z_values, IDL_msp );
1434                    /* Advance definition pointer over bounds */
1435                    array_defn_ptr +=
1436                                array_dims * (IDL_FIXED_BOUND_PAIR_WIDTH
1437                                                 + IDL_DATA_LIMIT_PAIR_WIDTH);
1438                    rpc_ss_init_new_array_ptrs( array_dims, Z_values,
1439                            array_defn_ptr,
1440                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
1441                            IDL_msp );
1442                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1443                                            (byte_p_t)Z_values);
1444		    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1445		      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1446					   (byte_p_t)bounds_list);
1447                }
1448                offset_vec_ptr++;
1449                break;
1450            case IDL_DT_CONF_ARRAY:
1451                /* Properties byte */
1452                type_has_pointers =
1453                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
1454                defn_vec_ptr++;
1455                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
1456                                                    /* Full array definition */
1457                IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
1458                if (type_has_pointers)
1459                {
1460                    /* Conformant array must be last field of struct */
1461                    offset = *offset_vec_ptr;
1462                    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1463                    array_dims = (idl_ulong_int)*array_defn_ptr;
1464                    array_defn_ptr++;   /* Now at (0 mod 4) */
1465                    rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr,
1466                                             (rpc_void_p_t)((idl_byte *)struct_addr + offset),
1467                                             struct_addr,
1468                                             struct_offset_vec_ptr,
1469                                             array_dims,
1470                                             conf_Z_values,
1471                                             TRUE,
1472                                             NULL,
1473                                             IDL_msp );
1474
1475                    rpc_ss_init_new_array_ptrs( array_dims, conf_Z_values,
1476                            array_defn_ptr,
1477                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
1478                            IDL_msp );
1479                }
1480                break;
1481            case IDL_DT_OPEN_ARRAY:
1482                /* Properties byte */
1483                type_has_pointers =
1484                             IDL_PROP_TEST(*defn_vec_ptr, IDL_PROP_HAS_PTRS);
1485                defn_vec_ptr++;
1486                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
1487                                                    /* Full array definition */
1488                IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
1489                if (type_has_pointers)
1490                {
1491                    /* Open array must be last field of struct */
1492                    offset = *offset_vec_ptr;
1493                    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1494                    array_dims = (idl_ulong_int)*array_defn_ptr;
1495                    array_defn_ptr++;   /* Now at (0 mod 4) */
1496                    rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr,
1497                                             (rpc_void_p_t)((idl_byte *)struct_addr + offset),
1498                                             struct_addr,
1499                                             struct_offset_vec_ptr,
1500                                             array_dims,
1501                                             conf_Z_values,
1502                                             TRUE,
1503                                             NULL,
1504                                             IDL_msp );
1505
1506                    array_defn_ptr += array_dims * IDL_DATA_LIMIT_PAIR_WIDTH;
1507                    rpc_ss_init_new_array_ptrs( array_dims, conf_Z_values,
1508                            array_defn_ptr,
1509                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
1510                            IDL_msp );
1511                }
1512                break;
1513            case IDL_DT_N_E_UNION:
1514                defn_vec_ptr++;     /* Discard properties byte */
1515                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);  /* Switch index */
1516                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);  /* Defn index */
1517                offset_vec_ptr++;
1518                break;
1519            case IDL_DT_ENC_UNION:
1520            case IDL_DT_FULL_PTR:
1521            case IDL_DT_TRANSMIT_AS:
1522            case IDL_DT_REPRESENT_AS:
1523            case IDL_DT_CS_TYPE:
1524                defn_vec_ptr++;     /* Discard properties byte */
1525                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);  /* Defn index */
1526                offset_vec_ptr++;
1527                break;
1528            case IDL_DT_UNIQUE_PTR:
1529                defn_vec_ptr++;     /* Discard properties byte */
1530                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);  /* Pointee defn */
1531                offset = *offset_vec_ptr;
1532                offset_vec_ptr++;
1533                *(rpc_void_p_t *)((idl_byte *)struct_addr+offset) = NULL;
1534                break;
1535            case IDL_DT_REF_PTR:
1536                defn_vec_ptr++;     /* Discard properties byte */
1537                IDL_GET_LONG_FROM_VECTOR(pointee_defn_index, defn_vec_ptr);
1538                offset = *offset_vec_ptr;
1539                offset_vec_ptr++;
1540                rpc_ss_alloc_pointer_target(
1541                               IDL_msp->IDL_type_vec+pointee_defn_index,
1542                               (rpc_void_p_t *)((idl_byte *)struct_addr+offset),
1543                               IDL_msp );
1544                break;
1545            case IDL_DT_CS_SHADOW:
1546                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* Shadow length */
1547                break;
1548            case IDL_DT_RANGE:
1549                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* range low-val */
1550                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr); /* range high-val */
1551                break;
1552            case IDL_DT_STRING:
1553            case IDL_DT_NDR_ALIGN_2:
1554            case IDL_DT_NDR_ALIGN_4:
1555            case IDL_DT_NDR_ALIGN_8:
1556            case IDL_DT_BEGIN_NESTED_STRUCT:
1557            case IDL_DT_END_NESTED_STRUCT:
1558            case IDL_DT_CS_ATTRIBUTE:
1559            case IDL_DT_CS_ARRAY:
1560            case IDL_DT_CS_RLSE_SHADOW:
1561            case IDL_DT_V1_ARRAY:
1562            case IDL_DT_V1_STRING:
1563            case IDL_DT_EOL:
1564                break;
1565            default:
1566#ifdef DEBUG_INTERP
1567                printf("rpc_ss_init_new_struct_ptrs:unrecognized type %d\n",
1568                        type_byte);
1569                exit(0);
1570#endif
1571                DCETHREAD_RAISE(rpc_x_coding_error);
1572        }
1573    } while (type_byte != IDL_DT_EOL);
1574
1575}
1576
1577/******************************************************************************/
1578/*                                                                            */
1579/*  Initialize the [ref] and [unique] pointers in arrays not allocated by     */
1580/*      the application                                                       */
1581/*                                                                            */
1582/******************************************************************************/
1583void rpc_ss_init_new_array_ptrs
1584(
1585    /* [in] */  idl_ulong_int dimensionality,
1586    /* [in] */  idl_ulong_int *Z_values,
1587    /* [in] */  idl_byte *defn_vec_ptr, /* On entry points at array base info */
1588    /* [in] */  rpc_void_p_t array_addr,
1589    IDL_msp_t IDL_msp
1590)
1591{
1592    idl_ulong_int element_count;
1593    unsigned32 i;
1594    idl_byte base_type;
1595    idl_ulong_int element_size;
1596    idl_ulong_int struct_defn_index;
1597    idl_ulong_int struct_offset_index;
1598    idl_byte *struct_defn_ptr;
1599    rpc_void_p_t *array_elt_addr;
1600
1601    element_count = 1;
1602    for (i=0; i<dimensionality; i++)
1603    {
1604        element_count *= Z_values[i];
1605    }
1606
1607    base_type = *defn_vec_ptr;
1608    defn_vec_ptr++;
1609    if (base_type == IDL_DT_FIXED_STRUCT)
1610    {
1611        /* Array of structures containing pointers */
1612        IDL_GET_LONG_FROM_VECTOR(struct_defn_index, defn_vec_ptr);
1613        struct_defn_ptr = IDL_msp->IDL_type_vec + struct_defn_index;
1614        IDL_GET_LONG_FROM_VECTOR(struct_offset_index, struct_defn_ptr);
1615        element_size = *(IDL_msp->IDL_offset_vec + struct_offset_index);
1616        /* Reset pointer to start of structure definition */
1617        struct_defn_ptr = IDL_msp->IDL_type_vec + struct_defn_index;
1618        for (i=0; i<element_count; i++)
1619        {
1620            rpc_ss_init_new_struct_ptrs( base_type, struct_defn_ptr,
1621                                            array_addr, NULL, IDL_msp );
1622            array_addr = (rpc_void_p_t)((idl_byte *)array_addr + element_size);
1623        }
1624    }
1625    else if ( (base_type != IDL_DT_FULL_PTR)
1626                && (base_type != IDL_DT_ENC_UNION) )
1627    {
1628        /* Array of [ref] or [unique] pointers */
1629        array_elt_addr = (rpc_void_p_t *)(array_addr);
1630        for (i=0; i<element_count; i++)
1631        {
1632            rpc_ss_init_new_store_ptrs( base_type, defn_vec_ptr,
1633                                         array_elt_addr, NULL, IDL_msp );
1634            array_elt_addr++;
1635        }
1636    }
1637}
1638
1639/******************************************************************************/
1640/*                                                                            */
1641/*  Initialize the [ref] and [unique] pointers in storage not allocated by    */
1642/*      the application                                                       */
1643/*                                                                            */
1644/******************************************************************************/
1645static void rpc_ss_init_new_store_ptrs
1646(
1647    /* [in] */ idl_byte storage_type,      /* Data type of allocated storage */
1648    /* [in] */ idl_byte *defn_vec_ptr,
1649                    /* For pointers - points to pointee definition */
1650                    /* For struct - points to structure definition */
1651                    /* For array - points to array definition */
1652    /* [in] */ rpc_void_p_t storage_addr,   /* Address of allocated storage */
1653    /* [in] */ idl_ulong_int *conf_Z_values,
1654                    /* Conformance information for conformant type, else NULL */
1655    IDL_msp_t IDL_msp
1656)
1657{
1658    idl_ulong_int dimensionality;
1659    idl_ulong_int *Z_values;
1660    IDL_bound_pair_t *bounds_list;
1661
1662    switch (storage_type)
1663    {
1664        case IDL_DT_FIXED_STRUCT:
1665        case IDL_DT_CONF_STRUCT:
1666            rpc_ss_init_new_struct_ptrs( storage_type, defn_vec_ptr,
1667                                         storage_addr, conf_Z_values, IDL_msp );
1668            break;
1669        case IDL_DT_FIXED_ARRAY:
1670        case IDL_DT_VARYING_ARRAY:
1671            dimensionality = (idl_ulong_int)*defn_vec_ptr;
1672            defn_vec_ptr++;
1673	    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1674		rpc_ss_fixed_bounds_from_vector(dimensionality, defn_vec_ptr,
1675						&bounds_list, IDL_msp);
1676	    else
1677	      bounds_list = (IDL_bound_pair_t *)defn_vec_ptr;
1678            Z_values = NULL;
1679            rpc_ss_Z_values_from_bounds( bounds_list,
1680                                           dimensionality, &Z_values, IDL_msp );
1681            defn_vec_ptr += dimensionality * IDL_FIXED_BOUND_PAIR_WIDTH;
1682            if (storage_type == IDL_DT_VARYING_ARRAY)
1683                defn_vec_ptr += dimensionality * IDL_DATA_LIMIT_PAIR_WIDTH;
1684            rpc_ss_init_new_array_ptrs( dimensionality, Z_values, defn_vec_ptr,
1685                storage_addr, IDL_msp );
1686            rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1687	    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1688	      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1689				   (byte_p_t)bounds_list);
1690            break;
1691        case IDL_DT_UNIQUE_PTR:
1692            *(rpc_void_p_t *)storage_addr = NULL;
1693            break;
1694        case IDL_DT_REF_PTR:
1695            rpc_ss_alloc_pointer_target( defn_vec_ptr,
1696                                      (rpc_void_p_t *)storage_addr, IDL_msp );
1697            break;
1698        default:
1699#ifdef DEBUG_INTERP
1700            printf("rpc_ss_init_new_store_ptrs:unrecognized type %d\n",
1701                        storage_type);
1702            exit(0);
1703#endif
1704            DCETHREAD_RAISE(rpc_x_coding_error);
1705    }
1706}
1707
1708/******************************************************************************/
1709/*                                                                            */
1710/*  Initialize the [ref] pointers in [out] only parameters                    */
1711/*                                                                            */
1712/******************************************************************************/
1713void rpc_ss_init_out_ref_ptrs
1714(
1715    /* [in,out] */ idl_byte **p_type_vec_ptr,
1716                            /* On entry type_vec_ptr points to type of parameter
1717                                         It is advanced over type definition */
1718    /* [in] */ rpc_void_p_t param_addr,
1719    IDL_msp_t IDL_msp
1720)
1721{
1722    idl_byte type_byte;
1723    idl_byte *type_vec_ptr = *p_type_vec_ptr;
1724    idl_ulong_int defn_index;
1725
1726    type_byte = *type_vec_ptr;
1727    type_vec_ptr++;
1728    switch (type_byte)
1729    {
1730        case IDL_DT_FIXED_STRUCT:
1731            type_vec_ptr++;     /* Ignore properties byte */
1732            IDL_GET_LONG_FROM_VECTOR( defn_index, type_vec_ptr );
1733            break;
1734        case IDL_DT_FIXED_ARRAY:
1735        case IDL_DT_VARYING_ARRAY:
1736            type_vec_ptr++;     /* Ignore properties byte */
1737            IDL_DISCARD_LONG_FROM_VECTOR( type_vec_ptr );  /* Full array defn */
1738            IDL_GET_LONG_FROM_VECTOR( defn_index, type_vec_ptr );
1739            break;
1740        case IDL_DT_REF_PTR:
1741            type_vec_ptr++;     /* Ignore properties byte */
1742            IDL_GET_LONG_FROM_VECTOR( defn_index, type_vec_ptr );
1743            break;
1744        default:
1745#ifdef DEBUG_INTERP
1746            printf("rpc_ss_init_out_ref_ptrs:unrecognized type %d\n",
1747                        type_byte);
1748            exit(0);
1749#endif
1750            DCETHREAD_RAISE(rpc_x_coding_error);
1751    }
1752    rpc_ss_init_new_store_ptrs( type_byte, IDL_msp->IDL_type_vec+defn_index,
1753                                param_addr, NULL, IDL_msp );
1754
1755    *p_type_vec_ptr = type_vec_ptr;
1756}
1757
1758/******************************************************************************/
1759/*                                                                            */
1760/*  Find out if a pointee to be unmarshalled is a non-fixed array or a        */
1761/*  conformant struct.  If so, check if pointee already unmarshalled and      */
1762/*  save this in p_pointee_desc->already_unmarshalled.  For the array case,   */
1763/*  build description of the bounds and, if necessary, data limits.           */
1764/*                                                                            */
1765/*  p_pointee_desc->dimensionality must be set on entry for the array case.   */
1766/*      0 indicates that no storage for array pointee data has been           */
1767/*      allocated.  If the pointee is an array with more dimensions than      */
1768/*      signified by this field, the current array pointee data storage is    */
1769/*      released and new storage allocated.                                   */
1770/*                                                                            */
1771/******************************************************************************/
1772void rpc_ss_ndr_unmar_pointee_desc
1773(
1774    /* [in] */ idl_byte pointer_type,   /* [ptr], [unique] or [ref] */
1775    /* [in] */  idl_byte *defn_vec_ptr, /* Points at definition of pointee */
1776    /* [out] */ IDL_pointee_desc_t *p_pointee_desc, /* Pointer to data structure
1777                                     to be filled in with pointee description */
1778    /* [in,out] */ rpc_void_p_t *p_pointer,
1779                    /* Entry - for a full pointer points to a node number
1780                       Exit - for a full pointer, if pointee has already been
1781                              unmarshalled, points to the address of the pointee
1782                       Not used for non-full pointer */
1783    IDL_msp_t IDL_msp
1784)
1785{
1786    idl_ulong_int array_defn_index;
1787    idl_byte *array_defn_ptr;
1788    IDL_bound_pair_t *bounds_list;
1789    idl_ulong_int dimensionality;
1790    rpc_void_p_t p_node;
1791    long already_unmarshalled;
1792    IDL_bound_pair_t *correl_bounds_list;
1793    IDL_bound_pair_t normal_correl_bounds_list[IDL_NORMAL_DIMS];
1794
1795    if (*defn_vec_ptr == IDL_DT_STRING)
1796        defn_vec_ptr++;
1797    p_pointee_desc->pointee_type = *defn_vec_ptr;
1798    if ( (p_pointee_desc->pointee_type != IDL_DT_VARYING_ARRAY)
1799        && (p_pointee_desc->pointee_type != IDL_DT_CONF_ARRAY)
1800        && (p_pointee_desc->pointee_type != IDL_DT_OPEN_ARRAY)
1801        && (p_pointee_desc->pointee_type != IDL_DT_CONF_STRUCT) )
1802    {
1803        return;
1804    }
1805
1806    /*
1807     * The pointee type is a non-fixed array or a conformant struct.  See if
1808     * the pointer is either NULL or the pointee has already been unmarshalled
1809     * so we know whether to unmarshall the Z and/or AB values for the pointee
1810     * construct.  Save the already unmarshalled flag for subsequent routine.
1811     */
1812    if (pointer_type == IDL_DT_FULL_PTR)
1813    {
1814        if (*p_pointer == NULL)
1815            return;
1816        p_node = (rpc_void_p_t)rpc_ss_inquire_pointer_to_node(
1817                                                    IDL_msp->IDL_node_table,
1818                                                    *(idl_ulong_int *)p_pointer,
1819                                                    &already_unmarshalled);
1820        p_pointee_desc->already_unmarshalled = already_unmarshalled;
1821        if (p_pointee_desc->already_unmarshalled)
1822        {
1823            *(rpc_void_p_t *)p_pointer = p_node;
1824            return;
1825        }
1826    }
1827    else if (pointer_type == IDL_DT_UNIQUE_PTR)
1828    {
1829#if 0
1830        if (*p_pointer == NULL)
1831            return;
1832#endif
1833        *(rpc_void_p_t *)p_pointer = IDL_NEW_NODE;
1834    }
1835
1836    /* Conformant struct Z value is unmarshalled in rpc_ss_ndr_unmar_pointee */
1837    if (p_pointee_desc->pointee_type == IDL_DT_CONF_STRUCT)
1838        return;
1839
1840    defn_vec_ptr++;
1841    p_pointee_desc->base_type_has_pointers =
1842                            IDL_PROP_TEST( *defn_vec_ptr, IDL_PROP_HAS_PTRS );
1843    defn_vec_ptr++;
1844    IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );   /* Full array definition */
1845    IDL_GET_LONG_FROM_VECTOR( array_defn_index, defn_vec_ptr );
1846    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1847    dimensionality = (idl_ulong_int)*array_defn_ptr;
1848    array_defn_ptr++;
1849
1850    /* Minimize the number of malloc's used to build the data structure */
1851    /* In code that follows, range list  will be allocated
1852        out of this memory, if necessary */
1853    if (dimensionality > p_pointee_desc->dimensionality)
1854    {
1855        if (p_pointee_desc->dimensionality > 0)
1856        {
1857            /* Some array description storage already exists, release it */
1858            rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1859                                            (byte_p_t)p_pointee_desc->Z_values);
1860        }
1861        p_pointee_desc->Z_values = (idl_ulong_int *) rpc_ss_mem_alloc(
1862                        &IDL_msp->IDL_mem_handle,
1863                         dimensionality
1864                           * ( sizeof(idl_ulong_int) /* Z_values */
1865                               + sizeof(IDL_bound_pair_t) /*  range list */ ) );
1866    }
1867    p_pointee_desc->dimensionality = dimensionality;
1868
1869    switch(p_pointee_desc->pointee_type)
1870    {
1871        case IDL_DT_VARYING_ARRAY:
1872            /* Build the range list in store allocated for the pointee desc */
1873            p_pointee_desc->range_list =  (IDL_bound_pair_t *)
1874                    (p_pointee_desc->Z_values + p_pointee_desc->dimensionality);
1875	    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1876	      rpc_ss_fixed_bounds_from_vector(p_pointee_desc->dimensionality,
1877                                         array_defn_ptr, &bounds_list, IDL_msp);
1878	    else
1879	      bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
1880            rpc_ss_Z_values_from_bounds( bounds_list,
1881                                         p_pointee_desc->dimensionality,
1882                                         &(p_pointee_desc->Z_values),
1883                                         IDL_msp );
1884	    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1885	      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1886				   (byte_p_t)bounds_list);
1887
1888            array_defn_ptr += p_pointee_desc->dimensionality * IDL_FIXED_BOUND_PAIR_WIDTH;
1889
1890            rpc_ss_ndr_unmar_range_list( p_pointee_desc->dimensionality,
1891                                     array_defn_ptr[p_pointee_desc->dimensionality *
1892                                                 IDL_DATA_LIMIT_PAIR_WIDTH],
1893                                     &p_pointee_desc->range_list, IDL_msp );
1894            rpc_ss_ndr_unmar_check_range_correlation( &array_defn_ptr,
1895                                     p_pointer,
1896                                     p_pointee_desc->struct_addr,
1897                                     p_pointee_desc->struct_offset_vec_ptr,
1898                                     p_pointee_desc->dimensionality,
1899                                     bounds_list,
1900                                     p_pointee_desc->range_list,
1901                                     IDL_msp );
1902            break;
1903        case IDL_DT_CONF_ARRAY:
1904            rpc_ss_ndr_unmar_Z_values( p_pointee_desc->dimensionality,
1905                                     &p_pointee_desc->Z_values, IDL_msp );
1906            rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr,
1907                                     p_pointer,
1908                                     p_pointee_desc->struct_addr,
1909                                     p_pointee_desc->struct_offset_vec_ptr,
1910                                     p_pointee_desc->dimensionality,
1911                                     p_pointee_desc->Z_values,
1912                                     FALSE,
1913                                     NULL,
1914                                     IDL_msp );
1915            break;
1916        case IDL_DT_OPEN_ARRAY:
1917            /* Build the range list in store allocated for the pointee desc */
1918            p_pointee_desc->range_list =  (IDL_bound_pair_t *)
1919                    (p_pointee_desc->Z_values + p_pointee_desc->dimensionality);
1920            rpc_ss_ndr_unmar_Z_values( p_pointee_desc->dimensionality,
1921                                     &p_pointee_desc->Z_values, IDL_msp );
1922            if (p_pointee_desc->dimensionality > IDL_NORMAL_DIMS)
1923                correl_bounds_list = NULL;
1924            else
1925                correl_bounds_list = normal_correl_bounds_list;
1926            rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr,
1927                                     p_pointer,
1928                                     p_pointee_desc->struct_addr,
1929                                     p_pointee_desc->struct_offset_vec_ptr,
1930                                     p_pointee_desc->dimensionality,
1931                                     p_pointee_desc->Z_values,
1932                                     FALSE,
1933                                     &correl_bounds_list,
1934                                     IDL_msp );
1935            rpc_ss_ndr_unmar_range_list( p_pointee_desc->dimensionality,
1936                                     array_defn_ptr[p_pointee_desc->dimensionality * IDL_DATA_LIMIT_PAIR_WIDTH],
1937                                     &p_pointee_desc->range_list, IDL_msp );
1938            rpc_ss_ndr_unmar_check_range_correlation( &array_defn_ptr,
1939                                     p_pointer,
1940                                     p_pointee_desc->struct_addr,
1941                                     p_pointee_desc->struct_offset_vec_ptr,
1942                                     p_pointee_desc->dimensionality,
1943                                     correl_bounds_list,
1944                                     p_pointee_desc->range_list,
1945                                     IDL_msp );
1946            if (p_pointee_desc->dimensionality > IDL_NORMAL_DIMS)
1947                rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)correl_bounds_list);
1948            break;
1949        default:
1950            DCETHREAD_RAISE( rpc_x_coding_error );
1951    }
1952    p_pointee_desc->array_base_defn_ptr = array_defn_ptr;
1953}
1954