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**      ndrui.c
80**
81**  FACILITY:
82**
83**      Interface Definition Language (IDL) Compiler
84**
85**  ABSTRACT:
86**
87**      NDR unmarshalling interpreter main module
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
99/*
100 *  Forward function references
101 */
102
103/* None */
104
105/******************************************************************************/
106/*                                                                            */
107/*  Calculate storage allocation size                                         */
108/*                                                                            */
109/******************************************************************************/
110idl_ulong_int rpc_ss_ndr_allocation_size
111(
112    /* [in] */  idl_ulong_int fixed_part_size,
113                    /* Size of the fixed part of the object to be allocated */
114    /* [in] */  idl_ulong_int dimensionality,
115                    /* 0 if object has no array part */
116    /* [in] */  idl_ulong_int *Z_values,
117                    /* Ignored if object has no array part */
118    /* [in] */  idl_byte *array_defn_ptr,
119                  /* If object has array part, points to array base info */
120    IDL_msp_t IDL_msp
121)
122{
123    idl_ulong_int allocation_size;
124    unsigned32 i;
125    idl_ulong_int dummy_defn_index; /* Throw-away array parameter */
126
127    if (dimensionality == 0)
128        allocation_size = 0;
129    else
130    {
131        /* Get size of array base type */
132        if (*array_defn_ptr == IDL_DT_STRING)
133        {
134            dimensionality--;
135            rpc_ss_get_string_base_desc(array_defn_ptr, &allocation_size,
136                                            &dummy_defn_index, IDL_msp);
137        }
138        else
139            allocation_size = rpc_ss_type_size(array_defn_ptr, IDL_msp);
140        /* Multiply by number of array elements */
141        for (i = 0; i < dimensionality; i++)
142        {
143            if (Z_values[i] > UINT_MAX / allocation_size)
144            {
145                DCETHREAD_RAISE(rpc_x_invalid_bound);
146            }
147            allocation_size *= Z_values[i];
148        }
149    }
150
151    /* Add in the size of the fixed part */
152    if (fixed_part_size > UINT_MAX - allocation_size)
153    {
154        DCETHREAD_RAISE(rpc_x_invalid_bound);
155    }
156    allocation_size += fixed_part_size;
157
158    return(allocation_size);
159}
160
161/******************************************************************************/
162/*                                                                            */
163/*  Allocate storage                                                          */
164/*                                                                            */
165/******************************************************************************/
166void rpc_ss_ndr_alloc_storage
167(
168    /* [in] */  idl_ulong_int fixed_part_size,
169                    /* Size of the fixed part of the object to be allocated */
170    /* [in] */  idl_ulong_int dimensionality,
171                    /* 0 if object has no array part */
172    /* [in] */  idl_ulong_int *Z_values,
173                    /* Ignored if object has no array part */
174    /* [in] */  idl_byte *array_defn_ptr,
175                  /* If object has array part, points to array base type info */
176    /* [out] */ rpc_void_p_t *p_storage_addr,
177    IDL_msp_t IDL_msp
178)
179{
180    idl_ulong_int allocation_size;
181
182    allocation_size = rpc_ss_ndr_allocation_size( fixed_part_size,
183                            dimensionality, Z_values, array_defn_ptr, IDL_msp );
184
185    /* Allocate storage - mem_alloc will raise an exception if necessary */
186    if (IDL_msp->IDL_side == IDL_server_side_k)
187    {
188        *p_storage_addr =
189                 (rpc_void_p_t)rpc_ss_mem_alloc(&(IDL_msp->IDL_mem_handle),
190                                                    allocation_size);
191    }
192    else
193    {
194        *p_storage_addr =
195	    rpc_allocator_allocate(&IDL_msp->IDL_allocator, allocation_size);
196        if (*p_storage_addr == NULL)
197            DCETHREAD_RAISE(rpc_x_no_memory);
198    }
199
200}
201
202/******************************************************************************/
203/*                                                                            */
204/*  Unmarshall a structure                                                    */
205/*                                                                            */
206/******************************************************************************/
207void rpc_ss_ndr_unmar_struct
208(
209    /* [in] */  idl_byte struct_type,   /* DT_FIXED_STRUCT or DT_CONF_STRUCT */
210    /* [in] */  idl_byte *defn_vec_ptr, /* Points to index into offset vector */
211    /* [in] */  rpc_void_p_t struct_addr,
212    /* [in] */  idl_ulong_int *Z_values,   /* Only used for DT_CONF_STRUCT */
213    /* [in] */  IDL_cs_shadow_elt_t *cs_shadow,
214                              /* NULL unless conformant struct with cs-shadow */
215    IDL_msp_t IDL_msp
216)
217{
218    idl_ulong_int offset_index;
219    idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */
220    idl_ulong_int *offset_vec_ptr;
221    idl_byte type_byte;
222    idl_ulong_int offset;
223    idl_ulong_int field_defn_index;
224    idl_byte *field_defn_ptr;
225    idl_ulong_int conf_dims;    /* Number of dimensions of conformance info */
226    IDL_bound_pair_t *range_list;
227    IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS];
228    IDL_bound_pair_t *bounds_list;
229    IDL_bound_pair_t range_bounds;
230    idl_ulong_int *varying_Z_values;    /* Used for varying array fields */
231    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
232    idl_ulong_int array_dims;   /* Number of dimensions of array */
233    idl_ulong_int unique_flag;  /* Wire form of [unique] pointer */
234    idl_ulong_int switch_value; /* Discarded [out] parameter */
235    intptr_t node_number = 0;
236    idl_ulong_int shadow_length;
237    idl_byte *shadow_defn_ptr = NULL;  /* Position after shadow_length */
238    IDL_bound_pair_t *correl_bounds_list;
239    IDL_bound_pair_t normal_correl_bounds_list[IDL_NORMAL_DIMS];
240
241    IDL_GET_LONG_FROM_VECTOR(offset_index,defn_vec_ptr);
242    struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index;
243
244    IDL_INIT_RANGE(range_bounds);
245
246    if ( (struct_type == IDL_DT_CONF_STRUCT)
247        || (struct_type == IDL_DT_V1_CONF_STRUCT) )
248    {
249        /* Discard the conformance info */
250        IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
251    }
252
253    if (*defn_vec_ptr == IDL_DT_CS_SHADOW)
254    {
255        defn_vec_ptr++;
256        IDL_GET_LONG_FROM_VECTOR(shadow_length, defn_vec_ptr);
257        if (cs_shadow == NULL)
258        {
259            cs_shadow = (IDL_cs_shadow_elt_t *) rpc_ss_mem_alloc
260                              (&IDL_msp->IDL_mem_handle,
261                                   shadow_length * sizeof(IDL_cs_shadow_elt_t));
262        }
263        shadow_defn_ptr = defn_vec_ptr;
264    }
265
266    offset_vec_ptr = struct_offset_vec_ptr + 1;
267                                        /* Skip over size at start of offsets */
268    /* Loop over the fields of the structure */
269    do {
270        type_byte = *defn_vec_ptr;
271        defn_vec_ptr++;
272        switch(type_byte)
273        {
274            case IDL_DT_BYTE:
275                offset = *offset_vec_ptr;
276                offset_vec_ptr++;
277                IDL_UNMAR_BYTE( (idl_byte *)struct_addr+offset );
278                IDL_CHECK_RANGE_BYTE( range_bounds, (idl_byte *)struct_addr + offset );
279                break;
280            case IDL_DT_CHAR:
281                offset = *offset_vec_ptr;
282                offset_vec_ptr++;
283                IDL_UNMAR_CHAR( (idl_byte *)struct_addr+offset );
284                IDL_CHECK_RANGE_CHAR( range_bounds, (idl_byte *)struct_addr + offset );
285                break;
286            case IDL_DT_BOOLEAN:
287                offset = *offset_vec_ptr;
288                offset_vec_ptr++;
289                IDL_UNMAR_BOOLEAN( (idl_byte *)struct_addr+offset );
290                IDL_CHECK_RANGE_BOOLEAN( range_bounds, (idl_byte *)struct_addr + offset );
291                break;
292            case IDL_DT_DOUBLE:
293                offset = *offset_vec_ptr;
294                offset_vec_ptr++;
295                IDL_UNMAR_DOUBLE( (idl_byte *)struct_addr+offset );
296                IDL_CHECK_RANGE_DOUBLE( range_bounds, (idl_byte *)struct_addr + offset );
297                break;
298            case IDL_DT_ENUM:
299                offset = *offset_vec_ptr;
300                offset_vec_ptr++;
301                IDL_UNMAR_ENUM( (idl_byte *)struct_addr+offset );
302                break;
303            case IDL_DT_FLOAT:
304                offset = *offset_vec_ptr;
305                offset_vec_ptr++;
306                IDL_UNMAR_FLOAT( (idl_byte *)struct_addr+offset );
307                IDL_CHECK_RANGE_FLOAT( range_bounds, (idl_byte *)struct_addr + offset );
308                break;
309            case IDL_DT_SMALL:
310                offset = *offset_vec_ptr;
311                offset_vec_ptr++;
312                IDL_UNMAR_SMALL( (idl_byte *)struct_addr+offset );
313                IDL_CHECK_RANGE_SMALL( range_bounds, (idl_byte *)struct_addr + offset );
314                break;
315            case IDL_DT_SHORT:
316                offset = *offset_vec_ptr;
317                offset_vec_ptr++;
318                IDL_UNMAR_SHORT( (idl_byte *)struct_addr+offset );
319                IDL_CHECK_RANGE_SHORT( range_bounds, (idl_byte *)struct_addr + offset );
320                break;
321            case IDL_DT_LONG:
322                offset = *offset_vec_ptr;
323                offset_vec_ptr++;
324                IDL_UNMAR_LONG( (idl_byte *)struct_addr+offset );
325                IDL_CHECK_RANGE_LONG( range_bounds, (idl_byte *)struct_addr + offset );
326                break;
327            case IDL_DT_HYPER:
328                offset = *offset_vec_ptr;
329                offset_vec_ptr++;
330                IDL_UNMAR_HYPER( (idl_byte *)struct_addr+offset );
331                break;
332            case IDL_DT_USMALL:
333                offset = *offset_vec_ptr;
334                offset_vec_ptr++;
335                IDL_UNMAR_USMALL( (idl_byte *)struct_addr+offset );
336                IDL_CHECK_RANGE_USMALL( range_bounds, (idl_byte *)struct_addr + offset );
337                break;
338            case IDL_DT_USHORT:
339                offset = *offset_vec_ptr;
340                offset_vec_ptr++;
341                IDL_UNMAR_USHORT( (idl_byte *)struct_addr+offset );
342                IDL_CHECK_RANGE_USHORT( range_bounds, (idl_byte *)struct_addr + offset );
343                break;
344            case IDL_DT_ULONG:
345                offset = *offset_vec_ptr;
346                offset_vec_ptr++;
347                IDL_UNMAR_ULONG( (idl_byte *)struct_addr+offset );
348                IDL_CHECK_RANGE_ULONG( range_bounds, (idl_byte *)struct_addr + offset );
349                break;
350            case IDL_DT_UHYPER:
351                offset = *offset_vec_ptr;
352                offset_vec_ptr++;
353                IDL_UNMAR_UHYPER( (idl_byte *)struct_addr+offset );
354                break;
355            case IDL_DT_V1_ENUM:
356                offset = *offset_vec_ptr;
357                offset_vec_ptr++;
358                IDL_UNMAR_V1_ENUM( (idl_byte *)struct_addr+offset );
359                break;
360            case IDL_DT_ERROR_STATUS:
361                offset = *offset_vec_ptr;
362                offset_vec_ptr++;
363                IDL_UNMAR_ERROR_STATUS( (idl_byte *)struct_addr+offset );
364                break;
365            case IDL_DT_FIXED_ARRAY:
366                defn_vec_ptr++;     /* Skip over properties byte */
367                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
368                                                    /* Full array definition */
369                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
370                offset = *offset_vec_ptr;
371                offset_vec_ptr++;
372                rpc_ss_ndr_unmar_fixed_arr(field_defn_index,
373                                           (idl_byte *)struct_addr+offset,
374                                           0, IDL_msp);
375                break;
376            case IDL_DT_VARYING_ARRAY:
377                defn_vec_ptr++;     /* Skip over properties byte */
378                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
379                                                    /* Full array definition */
380                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
381                offset = *offset_vec_ptr;
382                offset_vec_ptr++;
383                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
384                array_dims = (idl_ulong_int)*field_defn_ptr;
385                field_defn_ptr++;
386                /* By design field_defn_ptr is now at (0 mod 4) */
387		if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] !=
388		    NDR_LOCAL_INT_REP)
389		  rpc_ss_fixed_bounds_from_vector(array_dims, field_defn_ptr,
390                                                &bounds_list, IDL_msp);
391		else
392		  bounds_list = (IDL_bound_pair_t *)field_defn_ptr;
393                if (array_dims > IDL_NORMAL_DIMS)
394                {
395                    varying_Z_values = NULL;
396                    range_list = NULL;
397                }
398                else
399                {
400                    varying_Z_values = normal_Z_values;
401                    range_list = normal_range_list;
402                }
403                rpc_ss_Z_values_from_bounds(bounds_list, array_dims,
404                                             &varying_Z_values, IDL_msp);
405
406                field_defn_ptr += array_dims * IDL_FIXED_BOUND_PAIR_WIDTH;
407
408                rpc_ss_ndr_unmar_range_list( array_dims,
409                                             field_defn_ptr[array_dims * IDL_DATA_LIMIT_PAIR_WIDTH],
410                                             &range_list, IDL_msp );
411                rpc_ss_ndr_unmar_check_range_correlation( &field_defn_ptr,
412                                         (idl_byte *)struct_addr + offset,
413                                         struct_addr,
414                                         struct_offset_vec_ptr,
415                                         array_dims,
416                                         bounds_list,
417                                         range_list,
418                                         IDL_msp );
419                rpc_ss_ndr_u_var_or_open_arr( array_dims, varying_Z_values,
420                    field_defn_ptr, (idl_byte *)struct_addr+offset,
421                    range_list, 0, IDL_msp );
422                if (array_dims > IDL_NORMAL_DIMS)
423                {
424                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
425                                            (byte_p_t)range_list);
426                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
427                                            (byte_p_t)varying_Z_values);
428                }
429		if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] !=
430		    NDR_LOCAL_INT_REP)
431		  rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
432                                        (byte_p_t)bounds_list);
433                break;
434            case IDL_DT_CONF_ARRAY:
435                defn_vec_ptr++;     /* Skip over properties byte */
436                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
437                                                    /* Full array definition */
438                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
439                offset = *offset_vec_ptr;   /* Must be last field of struct */
440                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
441                conf_dims = (idl_ulong_int)*field_defn_ptr;
442                field_defn_ptr++;
443                rpc_ss_ndr_unmar_check_bounds_correlation( &field_defn_ptr,
444                                         (rpc_void_p_t)((idl_byte *)struct_addr + offset),
445                                         struct_addr,
446                                         struct_offset_vec_ptr,
447                                         conf_dims,
448                                         Z_values,
449                                         FALSE,
450                                         NULL,
451                                         IDL_msp );
452                rpc_ss_ndr_u_fix_or_conf_arr( conf_dims, Z_values,
453                         field_defn_ptr, (idl_byte *)struct_addr+offset,
454                         IDL_M_CONF_ARRAY, IDL_msp );
455                break;
456            case IDL_DT_OPEN_ARRAY:
457                defn_vec_ptr++;     /* Skip over properties byte */
458                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
459                                                    /* Full array definition */
460                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
461                offset = *offset_vec_ptr;   /* Must be last field of struct */
462                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
463                conf_dims = (idl_ulong_int)*field_defn_ptr;
464                field_defn_ptr++;
465                if (conf_dims > IDL_NORMAL_DIMS)
466                {
467                    correl_bounds_list = NULL;
468                    range_list = NULL;
469                }
470                else
471                {
472                    correl_bounds_list = normal_correl_bounds_list;
473                    range_list = normal_range_list;
474                }
475
476                rpc_ss_ndr_unmar_check_bounds_correlation( &field_defn_ptr,
477                                         (rpc_void_p_t)((idl_byte *)struct_addr + offset),
478                                         struct_addr,
479                                         struct_offset_vec_ptr,
480                                         conf_dims,
481                                         Z_values,
482                                         FALSE,
483                                         &correl_bounds_list,
484                                         IDL_msp );
485                rpc_ss_ndr_unmar_range_list( conf_dims,
486                                         field_defn_ptr[conf_dims * IDL_DATA_LIMIT_PAIR_WIDTH],
487                                         &range_list, IDL_msp );
488                rpc_ss_ndr_unmar_check_range_correlation( &field_defn_ptr,
489                                         (rpc_void_p_t)((idl_byte *)struct_addr + offset),
490                                         struct_addr,
491                                         struct_offset_vec_ptr,
492                                         conf_dims,
493                                         correl_bounds_list,
494                                         range_list,
495                                         IDL_msp );
496
497                rpc_ss_ndr_u_var_or_open_arr( conf_dims, Z_values,
498                         field_defn_ptr, (idl_byte *)struct_addr+offset,
499                         range_list, IDL_M_CONF_ARRAY, IDL_msp );
500
501                if (conf_dims > IDL_NORMAL_DIMS)
502                {
503                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
504                                            (byte_p_t)correl_bounds_list);
505                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
506                                            (byte_p_t)range_list);
507                }
508                break;
509            case IDL_DT_ENC_UNION:
510                defn_vec_ptr++;     /* Skip over properties byte */
511                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
512                offset = *offset_vec_ptr;
513                offset_vec_ptr++;
514                rpc_ss_ndr_u_enc_union_or_ptees( (idl_byte *)struct_addr+offset,
515                                          field_defn_index, idl_false, IDL_msp);
516                break;
517            case IDL_DT_N_E_UNION:
518                defn_vec_ptr++;     /* Skip over properties byte */
519                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Switch index */
520                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
521                offset = *offset_vec_ptr;
522                offset_vec_ptr++;
523                rpc_ss_ndr_unmar_n_e_union( (idl_byte *)struct_addr+offset,
524                                      field_defn_index, &switch_value, IDL_msp);
525                break;
526            case IDL_DT_FULL_PTR:
527	    {
528		idl_ulong_int _node;
529                defn_vec_ptr++;     /* Properties byte */
530                /* Unmarshall the node number into the space for the pointer */
531                offset = *offset_vec_ptr;
532                offset_vec_ptr++;
533                IDL_UNMAR_ULONG( &_node );
534		node_number = (intptr_t) _node;
535                *(rpc_void_p_t *)((idl_byte *)struct_addr+offset)
536                                                    = (rpc_void_p_t)node_number;
537                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
538                                        /* Indirection to pointee type */
539                break;
540	    }
541            case IDL_DT_UNIQUE_PTR:
542                defn_vec_ptr++;     /* Properties byte */
543                IDL_UNMAR_ULONG( &unique_flag );
544                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
545                                        /* Indirection to pointee type */
546                offset = *offset_vec_ptr;
547                offset_vec_ptr++;
548                if (unique_flag == 0)
549                {
550                    *(rpc_void_p_t *)((idl_byte *)struct_addr+offset) = NULL;
551                }
552                else
553                {
554                    *(rpc_void_p_t *)((idl_byte *)struct_addr+offset)
555                                         = IDL_NEW_NODE;
556                }
557                break;
558            case IDL_DT_REF_PTR:
559                defn_vec_ptr++;     /* Properties byte */
560                /* Skip over the longword place holder */
561                IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
562                rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
563                IDL_msp->IDL_mp += 4;
564                IDL_msp->IDL_left_in_buff -= 4;
565                IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );
566                                        /* Indirection to pointee type */
567                offset_vec_ptr++;
568                break;
569            case IDL_DT_IGNORE:
570                /* Skip over the longword place holder */
571                IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
572                rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
573                IDL_msp->IDL_mp += 4;
574                IDL_msp->IDL_left_in_buff -= 4;
575                offset_vec_ptr++;
576                break;
577            case IDL_DT_STRING:
578                /* Varying/open array code will do the right thing */
579                break;
580            case IDL_DT_TRANSMIT_AS:
581            case IDL_DT_REPRESENT_AS:
582                defn_vec_ptr++;     /* Skip over properties byte */
583                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
584                offset = *offset_vec_ptr;
585                offset_vec_ptr++;
586                rpc_ss_ndr_unmar_xmit_as(field_defn_index,
587                                 (idl_byte *)struct_addr+offset, NULL, IDL_msp);
588                break;
589#if 0
590            case IDL_DT_INTERFACE:
591                defn_vec_ptr++;     /* Skip over properties byte */
592                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
593                offset = *offset_vec_ptr;
594                offset_vec_ptr++;
595                rpc_ss_ndr_unmar_interface(field_defn_index, (idl_byte *)struct_addr+offset, NULL, IDL_msp);
596                break;
597#endif
598
599            case IDL_DT_V1_ARRAY:
600                type_byte = *defn_vec_ptr;  /* DT_VARYING or DT_OPEN */
601                defn_vec_ptr += 2;   /* DT_VARYING/DT_OPEN and properties */
602                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
603                                                    /* Full array definition */
604                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
605                offset = *offset_vec_ptr;
606                offset_vec_ptr++;
607                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
608                array_dims = (idl_ulong_int)*field_defn_ptr;
609                field_defn_ptr++;
610                /* By design field_defn_ptr is now at (0 mod 4) */
611                if (type_byte == IDL_DT_VARYING_ARRAY)
612                {
613                    field_defn_ptr += array_dims * (IDL_FIXED_BOUND_PAIR_WIDTH
614                                                   + IDL_DATA_LIMIT_PAIR_WIDTH);
615                }
616                else
617                {
618                    IDL_ADV_DEFN_PTR_OVER_BOUNDS( field_defn_ptr, array_dims );
619                    /* Advance array defn ptr over data limit info */
620                    field_defn_ptr += array_dims *  IDL_DATA_LIMIT_PAIR_WIDTH;
621                }
622                rpc_ss_ndr_u_v1_varying_arr( (idl_byte *)struct_addr+offset,
623                                             field_defn_ptr, 0, IDL_msp );
624                break;
625            case IDL_DT_V1_STRING:
626                defn_vec_ptr += 2;  /* DT_VARYING_ARRAY and properties */
627                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
628                                                        /* Full array defn */
629                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
630                                                      /* Flattened array defn */
631                offset = *offset_vec_ptr;
632                offset_vec_ptr++;
633                rpc_ss_ndr_unmar_v1_string((idl_byte *)struct_addr+offset,
634                                           0, IDL_msp);
635                break;
636            case IDL_DT_CS_ATTRIBUTE:
637                /* Discard the value on the wire. Later a correct value will
638                    be written from the cs-shadow */
639                rpc_ss_ndr_unmar_scalar(*defn_vec_ptr,
640                                        (rpc_void_p_t)&switch_value, IDL_msp);
641                defn_vec_ptr++;     /* Type of attribute */
642                offset_vec_ptr++;
643                break;
644            case IDL_DT_CS_ARRAY:
645                offset = *offset_vec_ptr;
646                rpc_ss_ndr_unmar_cs_array(
647                        (rpc_void_p_t)((idl_byte *)struct_addr+offset),
648                        cs_shadow, Z_values,
649                        offset_vec_ptr - (struct_offset_vec_ptr + 1),
650                        &defn_vec_ptr, IDL_msp);
651                offset_vec_ptr++;
652                break;
653            case IDL_DT_CS_TYPE:
654                defn_vec_ptr++;     /* Skip over properties byte */
655                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
656                offset = *offset_vec_ptr;
657                offset_vec_ptr++;
658                rpc_ss_ndr_unmar_cs_char(
659                                 (rpc_void_p_t)((idl_byte *)struct_addr+offset),
660                                 field_defn_index, IDL_msp);
661                break;
662            case IDL_DT_CS_RLSE_SHADOW:
663                rpc_ss_ndr_u_struct_cs_shadow(struct_addr, struct_type,
664                            offset_index, shadow_defn_ptr, cs_shadow, IDL_msp);
665                break;
666            case IDL_DT_NDR_ALIGN_2:
667                IDL_UNMAR_ALIGN_MP( IDL_msp, 2 );
668                break;
669            case IDL_DT_NDR_ALIGN_4:
670                IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
671                break;
672            case IDL_DT_NDR_ALIGN_8:
673                IDL_UNMAR_ALIGN_MP( IDL_msp, 8 );
674                break;
675            case IDL_DT_RANGE:
676                IDL_GET_RANGE_FROM_VECTOR( range_bounds, defn_vec_ptr );
677                break;
678            case IDL_DT_BEGIN_NESTED_STRUCT:
679            case IDL_DT_END_NESTED_STRUCT:
680            case IDL_DT_EOL:
681                break;
682            default:
683#ifdef DEBUG_INTERP
684                printf("rpc_ss_ndr_unmar_struct:unrecognized type %d\n",
685                        type_byte);
686                exit(0);
687#endif
688                DCETHREAD_RAISE(rpc_x_coding_error);
689        }
690    } while (type_byte != IDL_DT_EOL);
691
692}
693
694/******************************************************************************/
695/*                                                                            */
696/*  Unmarshall an array by copying from the receive buffer                    */
697/*  On entry IDL_mp is already aligned to the base type requirement           */
698/*                                                                            */
699/******************************************************************************/
700void rpc_ss_ndr_unmar_by_copying
701(
702    /* [in] */  idl_ulong_int element_count,
703    /* [in] */  idl_ulong_int element_size,
704    /* [in] */  rpc_void_p_t array_addr,
705    IDL_msp_t IDL_msp
706)
707{
708    idl_ulong_int bytes_required;   /* Number of bytes left to copy */
709    idl_ulong_int bytes_to_copy;  /* Number of bytes to copy from this buffer */
710
711    bytes_required = element_count * element_size;
712    while (bytes_required != 0)
713    {
714        rpc_ss_ndr_unmar_check_buffer( IDL_msp, IDL_msp->IDL_left_in_buff );
715        if (bytes_required > IDL_msp->IDL_left_in_buff)
716            bytes_to_copy = IDL_msp->IDL_left_in_buff;
717        else
718            bytes_to_copy = bytes_required;
719        memcpy(array_addr, IDL_msp->IDL_mp, bytes_to_copy);
720        IDL_msp->IDL_mp += bytes_to_copy;
721        IDL_msp->IDL_left_in_buff -= bytes_to_copy;
722        bytes_required -= bytes_to_copy;
723        array_addr = (rpc_void_p_t)((idl_byte *)array_addr + bytes_to_copy);
724    }
725}
726
727/******************************************************************************/
728/*                                                                            */
729/*  Unmarshall a contiguous set of elements one by one                        */
730/*                                                                            */
731/******************************************************************************/
732void rpc_ss_ndr_unmar_by_looping
733(
734    /* [in] */  idl_ulong_int element_count,
735    /* [in] */  idl_byte base_type,
736    /* [in] */  rpc_void_p_t array_addr,
737    /* [in] */  idl_ulong_int element_size,
738                         /* Used if array of struct, union or array of string */
739    /* [in] */  idl_ulong_int element_defn_index,
740                                /* Used if array of struct or array of string */
741    IDL_msp_t IDL_msp
742)
743{
744    unsigned32 i;
745    idl_ulong_int unique_flag;  /* Wire form of [unique] pointer */
746    idl_ulong_int element_byte_count;   /* Number of bytes elements occupy */
747    intptr_t node_number = 0;
748    idl_byte *element_defn_ptr;
749    unsigned long xmit_data_size;   /* [transmit_as] - size of xmitted type */
750    rpc_void_p_t xmit_data_buff = NULL;     /* Address of storage [transmit_as]
751                                                type can be unmarshalled into */
752
753    if (base_type == IDL_DT_REF_PTR)
754    {
755        /* Unmarshalling field which is array of [ref] pointers */
756        IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
757        while (element_count > 0)
758        {
759            element_byte_count = 4 * element_count;
760            if ( element_byte_count > IDL_msp->IDL_left_in_buff )
761            {
762                element_count -= IDL_msp->IDL_left_in_buff / 4;
763                /* Force a buffer change */
764                rpc_ss_ndr_unmar_check_buffer( IDL_msp, element_byte_count );
765            }
766            else
767            {
768                IDL_msp->IDL_mp += element_byte_count;
769                IDL_msp->IDL_left_in_buff -= element_byte_count;
770                element_count = 0;
771            }
772        }
773        return;
774    }
775
776    if ( (base_type == IDL_DT_TRANSMIT_AS)
777        || (base_type == IDL_DT_REPRESENT_AS) )
778    {
779        /* If possible, allocate a buffer into which elements of the transmitted
780            type can be unmarshalled */
781        element_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index;
782        IDL_DISCARD_LONG_FROM_VECTOR( element_defn_ptr );
783                                             /* Presented type size index */
784        IDL_DISCARD_LONG_FROM_VECTOR( element_defn_ptr );   /* Rtn vec index */
785        if (*element_defn_ptr == IDL_DT_STRING)
786            element_defn_ptr++;
787        xmit_data_size = rpc_ss_type_size(element_defn_ptr, IDL_msp);
788        if (xmit_data_size != 0)
789            xmit_data_buff = (rpc_void_p_t)rpc_ss_mem_alloc
790                                    (&IDL_msp->IDL_mem_handle, xmit_data_size);
791    }
792
793    for (i=0; i<element_count; i++)
794    {
795        switch (base_type)
796        {
797            case IDL_DT_BOOLEAN:
798                IDL_UNMAR_BOOLEAN( array_addr );
799                array_addr = (rpc_void_p_t)((idl_boolean *)(array_addr) + 1);
800                break;
801            case IDL_DT_BYTE:
802                IDL_UNMAR_BYTE( array_addr );
803                array_addr = (rpc_void_p_t)((idl_byte *)(array_addr) + 1);
804                break;
805            case IDL_DT_CHAR:
806                IDL_UNMAR_CHAR( array_addr );
807                array_addr = (rpc_void_p_t)((idl_char *)(array_addr) + 1);
808                break;
809            case IDL_DT_DOUBLE:
810                IDL_UNMAR_DOUBLE( array_addr );
811                array_addr = (rpc_void_p_t)((idl_long_float *)(array_addr) + 1);
812                break;
813            case IDL_DT_ENUM:
814                IDL_UNMAR_ENUM( array_addr );
815                array_addr = (rpc_void_p_t)((int *)(array_addr) + 1);
816                break;
817            case IDL_DT_V1_ENUM:
818                IDL_UNMAR_V1_ENUM( array_addr );
819                array_addr = (rpc_void_p_t)((int *)(array_addr) + 1);
820                break;
821            case IDL_DT_FLOAT:
822                IDL_UNMAR_FLOAT( array_addr );
823                array_addr = (rpc_void_p_t)((idl_short_float *)(array_addr) + 1);
824                break;
825            case IDL_DT_SMALL:
826                IDL_UNMAR_SMALL( array_addr );
827                array_addr = (rpc_void_p_t)((idl_small_int *)(array_addr) + 1);
828                break;
829            case IDL_DT_SHORT:
830                IDL_UNMAR_SHORT( array_addr );
831                array_addr = (rpc_void_p_t)((idl_short_int *)(array_addr) + 1);
832                break;
833            case IDL_DT_LONG:
834                IDL_UNMAR_LONG( array_addr );
835                array_addr = (rpc_void_p_t)((idl_long_int *)(array_addr) + 1);
836                break;
837            case IDL_DT_HYPER:
838                IDL_UNMAR_HYPER( array_addr );
839                array_addr = (rpc_void_p_t)((idl_hyper_int *)(array_addr) + 1);
840                break;
841            case IDL_DT_USMALL:
842                IDL_UNMAR_USMALL( array_addr );
843                array_addr = (rpc_void_p_t)((idl_usmall_int *)(array_addr) + 1);
844                break;
845            case IDL_DT_USHORT:
846                IDL_UNMAR_USHORT( array_addr );
847                array_addr = (rpc_void_p_t)((idl_ushort_int *)(array_addr) + 1);
848                break;
849            case IDL_DT_ULONG:
850                IDL_UNMAR_ULONG( array_addr );
851                array_addr = (rpc_void_p_t)((idl_ulong_int *)(array_addr) + 1);
852                break;
853            case IDL_DT_ERROR_STATUS:
854                IDL_UNMAR_ERROR_STATUS( array_addr );
855                array_addr = (rpc_void_p_t)((idl_ulong_int *)(array_addr) + 1);
856                break;
857            case IDL_DT_UHYPER:
858                IDL_UNMAR_UHYPER( array_addr );
859                array_addr = (rpc_void_p_t)((idl_uhyper_int *)(array_addr) + 1);
860                break;
861            case IDL_DT_FIXED_STRUCT:
862                rpc_ss_ndr_unmar_struct( base_type,
863                                     IDL_msp->IDL_type_vec + element_defn_index,
864                                         array_addr, NULL, NULL, IDL_msp );
865                array_addr = (rpc_void_p_t)
866                                      ((idl_byte *)(array_addr) + element_size);
867                break;
868            case IDL_DT_FIXED_ARRAY:
869                /* Base type of pipe is array */
870                rpc_ss_ndr_unmar_fixed_arr( element_defn_index, array_addr,
871                                            0, IDL_msp );
872                array_addr = (rpc_void_p_t)
873                                      ((idl_byte *)(array_addr) + element_size);
874                break;
875            case IDL_DT_ENC_UNION:
876                rpc_ss_ndr_u_enc_union_or_ptees( array_addr, element_defn_index,
877                                                    idl_false, IDL_msp );
878                array_addr = (rpc_void_p_t)
879                                    ((idl_byte *)(array_addr) + element_size);
880                break;
881            case IDL_DT_FULL_PTR:
882	    {
883	        idl_ulong_int _node;
884                /* Unmarshall the node number into the space for the pointer */
885                IDL_UNMAR_ULONG( &_node );
886		node_number = (intptr_t) _node;
887                *(rpc_void_p_t *)(array_addr) = (rpc_void_p_t)node_number;
888                array_addr = (rpc_void_p_t)((rpc_void_p_t *)(array_addr) + 1);
889                break;
890	    }
891            case IDL_DT_UNIQUE_PTR:
892                IDL_UNMAR_ULONG( &unique_flag );
893                if (unique_flag == 0)
894                    *(rpc_void_p_t *)array_addr = NULL;
895                else if ( *(rpc_void_p_t *)array_addr == NULL )
896                    *(rpc_void_p_t *)array_addr = IDL_NEW_NODE;
897                array_addr = (rpc_void_p_t)((rpc_void_p_t *)(array_addr) + 1);
898                break;
899            case IDL_DT_STRING:
900                {
901                    idl_byte *element_defn_ptr;
902                    idl_ulong_int A, B;
903                    idl_ulong_int base_type_size;
904
905                    element_defn_ptr = IDL_msp->IDL_type_vec
906                                        + element_defn_index
907                                        + 1     /* Dimensionality */
908                                        + IDL_FIXED_BOUND_PAIR_WIDTH
909                                        + IDL_DATA_LIMIT_PAIR_WIDTH;
910                    /* Now pointing at base type of string */
911                    base_type_size = rpc_ss_type_size(element_defn_ptr,
912                                                                     IDL_msp);
913                    IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
914                    rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
915                    rpc_convert_ulong_int(IDL_msp->IDL_drep, ndr_g_local_drep,
916                                 IDL_msp->IDL_mp, A);
917                    IDL_msp->IDL_mp += 4;
918                    IDL_msp->IDL_left_in_buff -= 4;
919                    rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
920                    rpc_convert_ulong_int(IDL_msp->IDL_drep, ndr_g_local_drep,
921                                 IDL_msp->IDL_mp, B);
922                    IDL_msp->IDL_mp += 4;
923                    IDL_msp->IDL_left_in_buff -= 4;
924                    if ( ( (*element_defn_ptr == IDL_DT_CHAR)
925                          && (IDL_msp->IDL_drep.char_rep
926                                                 != ndr_g_local_drep.char_rep) )
927                        ||
928                           ( (*element_defn_ptr == IDL_DT_USHORT
929                              || *element_defn_ptr == IDL_DT_ULONG)
930                            && (IDL_msp->IDL_drep.int_rep
931                                                != ndr_g_local_drep.int_rep) ) )
932                    {
933                        rpc_ss_ndr_unmar_by_looping(B, *element_defn_ptr,
934                                                     array_addr, 1, 0, IDL_msp);
935                    }
936                    else
937                        rpc_ss_ndr_unmar_by_copying(B, base_type_size,
938                                                    array_addr, IDL_msp);
939                }
940                array_addr = (rpc_void_p_t)
941                                      ((idl_byte *)(array_addr) + element_size);
942                break;
943            case IDL_DT_TRANSMIT_AS:
944            case IDL_DT_REPRESENT_AS:
945                rpc_ss_ndr_unmar_xmit_as(element_defn_index, array_addr,
946                                                       xmit_data_buff, IDL_msp);
947                array_addr = (rpc_void_p_t)
948                                      ((idl_byte *)(array_addr) + element_size);
949                break;
950            case IDL_DT_V1_STRING:
951                rpc_ss_ndr_unmar_v1_string(array_addr, 0, IDL_msp);
952                array_addr = (rpc_void_p_t)
953                                      ((idl_byte *)(array_addr) + element_size);
954                break;
955            default:
956#ifdef DEBUG_INTERP
957                printf(
958                      "rpc_ss_ndr_unmar_by_looping:unrecognized type %d\n",
959                        base_type);
960                exit(0);
961#endif
962                DCETHREAD_RAISE(rpc_x_coding_error);
963        }
964    }
965    if (xmit_data_buff != NULL)
966        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,(byte_p_t)xmit_data_buff);
967}
968
969/******************************************************************************/
970/*                                                                            */
971/* Unmarshall a fixed or conformant array                                     */
972/*                                                                            */
973/******************************************************************************/
974void rpc_ss_ndr_u_fix_or_conf_arr
975(
976    /* [in] */  idl_ulong_int dimensionality,
977    /* [in] */  idl_ulong_int *Z_values,
978    /* [in] */  idl_byte *defn_vec_ptr, /* On entry points to array base info */
979    /* [in] */  rpc_void_p_t array_addr,
980    /* [in] */  idl_ulong_int flags ATTRIBUTE_UNUSED,
981    IDL_msp_t IDL_msp
982)
983{
984    idl_ulong_int element_count;
985    unsigned32 i;
986    idl_byte base_type;
987    idl_boolean unmarshall_by_copying;
988    idl_ulong_int element_size = 0;
989    idl_ulong_int element_defn_index;
990    idl_ulong_int struct_offset_index;
991    idl_byte *struct_defn_ptr;
992
993    if ( (*defn_vec_ptr == IDL_DT_STRING)
994        || (*defn_vec_ptr == IDL_DT_V1_STRING) )
995    {
996        /* Arrays of strings have a special representation */
997        dimensionality--;
998    }
999
1000    element_count = 1;
1001    for (i=0; i<dimensionality; i++)
1002    {
1003        element_count *= Z_values[i];
1004    }
1005
1006    if (element_count == 0)
1007        return;
1008
1009    rpc_ss_ndr_arr_align_and_opt( IDL_unmarshalling_k, dimensionality,
1010                                    &base_type, defn_vec_ptr,
1011                                    &unmarshall_by_copying, IDL_msp );
1012
1013    if (base_type == IDL_DT_REF_PTR)
1014    {
1015        /* Arrays of [ref] pointers are not marshalled */
1016        return;
1017    }
1018
1019    if (unmarshall_by_copying)
1020    {
1021        element_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
1022        if (base_type == IDL_DT_FIXED_STRUCT)
1023        {
1024            /* There is a problem because for the last element of the
1025              structure we may not want to unmarshall sizeof(structure) bytes */
1026            element_count--;        /* So do the last one separately */
1027        }
1028        if (element_count != 0)
1029        {
1030            rpc_ss_ndr_unmar_by_copying(element_count, element_size, array_addr,
1031                                                                     IDL_msp);
1032        }
1033        if (base_type == IDL_DT_FIXED_STRUCT)
1034        {
1035            /* Marshall the last element separately */
1036            defn_vec_ptr += 2;  /* See comment below */
1037            IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1038            rpc_ss_ndr_unmar_struct(base_type,
1039                                    IDL_msp->IDL_type_vec + element_defn_index,
1040                                    (rpc_void_p_t)((idl_byte *)array_addr
1041                                                + element_count * element_size),
1042                                    NULL, NULL, IDL_msp);
1043        }
1044        return;
1045    }
1046
1047    if ( (base_type == IDL_DT_FIXED_STRUCT)
1048         || (base_type == IDL_DT_ENC_UNION)
1049         || (base_type == IDL_DT_TRANSMIT_AS)
1050         || (base_type == IDL_DT_REPRESENT_AS) )
1051    {
1052        defn_vec_ptr += 2;  /* Discard type and properties */
1053        /* If we are unmarshalling an array, not a pipe, defn_vec_ptr was
1054            4-byte aligned and DT_MODIFIED and modifier are discarded
1055            by the +=2 followed by GET_LONG */
1056        IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1057        struct_defn_ptr = IDL_msp->IDL_type_vec + element_defn_index;
1058        IDL_GET_LONG_FROM_VECTOR(struct_offset_index, struct_defn_ptr);
1059        element_size = *(IDL_msp->IDL_offset_vec + struct_offset_index);
1060    }
1061    else if ( (base_type == IDL_DT_STRING)
1062            || (base_type == IDL_DT_V1_STRING) )
1063    {
1064        rpc_ss_get_string_base_desc( defn_vec_ptr, &element_size,
1065                                        &element_defn_index, IDL_msp );
1066    }
1067    else if (base_type == IDL_DT_FIXED_ARRAY)
1068    {
1069        /* Base type of pipe is array */
1070        element_size = rpc_ss_type_size( defn_vec_ptr, IDL_msp );
1071        defn_vec_ptr += 2;  /* Base type and properties byte */
1072        IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );   /* Full array defn */
1073        IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1074    }
1075    else if (base_type == IDL_DT_INTERFACE)
1076    {
1077        element_size = sizeof(void*);
1078        defn_vec_ptr += 2; /* skip base type and props */
1079        IDL_GET_LONG_FROM_VECTOR(element_defn_index, defn_vec_ptr);
1080    }
1081    else
1082        element_defn_index = 0;
1083
1084    rpc_ss_ndr_unmar_by_looping( element_count,
1085                                 base_type, array_addr, element_size,
1086                                 element_defn_index, IDL_msp);
1087}
1088
1089/******************************************************************************/
1090/*                                                                            */
1091/*  Unmarshall a fixed array                                                  */
1092/*                                                                            */
1093/******************************************************************************/
1094void rpc_ss_ndr_unmar_fixed_arr
1095(
1096    /* [in] */  idl_ulong_int defn_index,
1097    /* [in] */  rpc_void_p_t array_addr,
1098    /* [in] */  idl_ulong_int flags,
1099    IDL_msp_t IDL_msp
1100)
1101{
1102    idl_byte *defn_vec_ptr;
1103    idl_ulong_int dimensionality;
1104    idl_ulong_int *Z_values;
1105    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
1106    IDL_bound_pair_t *bounds_list;
1107
1108    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
1109    dimensionality = (idl_ulong_int)*defn_vec_ptr;
1110    defn_vec_ptr++;     /* By design, alignment is now (0 mod 4) */
1111    if (dimensionality > IDL_NORMAL_DIMS)
1112        Z_values = NULL;
1113    else
1114        Z_values = normal_Z_values;
1115    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1116      rpc_ss_fixed_bounds_from_vector(dimensionality, defn_vec_ptr, &bounds_list,
1117                                    IDL_msp);
1118    else
1119      bounds_list = (IDL_bound_pair_t *)defn_vec_ptr;
1120    rpc_ss_Z_values_from_bounds( bounds_list, dimensionality, &Z_values,
1121                                                                   IDL_msp );
1122    defn_vec_ptr += dimensionality * IDL_FIXED_BOUND_PAIR_WIDTH;
1123    rpc_ss_ndr_u_fix_or_conf_arr( dimensionality, Z_values, defn_vec_ptr,
1124                                     array_addr, flags, IDL_msp);
1125    if (dimensionality > IDL_NORMAL_DIMS)
1126        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1127    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1128      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1129}
1130
1131/******************************************************************************/
1132/*                                                                            */
1133/*  Unmarshall A,B pairs and build a range list from them                     */
1134/*                                                                            */
1135/******************************************************************************/
1136void rpc_ss_ndr_unmar_range_list
1137(
1138    /* [in] */  idl_ulong_int dimensionality,
1139    /* [in] */  idl_byte base_type,     /* Base type of the varying array */
1140    /* [out] */ IDL_bound_pair_t **p_range_list,
1141    IDL_msp_t IDL_msp
1142)
1143{
1144    IDL_bound_pair_t *range_list;
1145    unsigned32 i;
1146    idl_ulong_int A,B;
1147
1148    if (base_type == IDL_DT_STRING)
1149        dimensionality--;
1150    if (*p_range_list == NULL)
1151    {
1152        range_list = (IDL_bound_pair_t *)rpc_ss_mem_alloc
1153          (&IDL_msp->IDL_mem_handle, dimensionality * sizeof(IDL_bound_pair_t));
1154        *p_range_list = range_list;
1155    }
1156    else
1157        range_list = *p_range_list;
1158
1159    for (i=0; i<dimensionality; i++)
1160    {
1161        IDL_UNMAR_ULONG( &A );
1162        range_list[i].lower = A;
1163        IDL_UNMAR_ULONG( &B );
1164        range_list[i].upper = A + B;
1165    }
1166}
1167
1168/******************************************************************************/
1169/*                                                                            */
1170/*  Unmarshall a varying or open array                                        */
1171/*                                                                            */
1172/******************************************************************************/
1173void rpc_ss_ndr_u_var_or_open_arr
1174(
1175    /* [in] */  idl_ulong_int dimensionality,
1176    /* [in] */  idl_ulong_int *Z_values,
1177    /* [in] */  idl_byte *defn_vec_ptr, /* On entry points at array base info */
1178    /* [in] */  rpc_void_p_t array_addr,
1179    /* [in] */ IDL_bound_pair_t *range_list,
1180    /* [in] */ idl_ulong_int flags,
1181    IDL_msp_t IDL_msp
1182)
1183{
1184    idl_byte base_type;
1185    idl_ulong_int element_defn_index = 0;
1186    idl_ulong_int element_size;
1187    idl_boolean unmarshall_by_copying;
1188    rpc_void_p_t copy_addr;    /* Address to be used in unmar by copying */
1189    idl_boolean contiguous;
1190    idl_ulong_int element_count;
1191    IDL_varying_control_t *control_data;
1192    IDL_varying_control_t normal_control_data[IDL_NORMAL_DIMS];
1193    idl_ulong_int i;
1194    idl_byte *inner_slice_address;  /* Address of 1-dim subset of array */
1195    int dim;    /* Index through array dimensions. Has to be signed! */
1196    char *cptr;
1197
1198    if ( (*defn_vec_ptr == IDL_DT_STRING)
1199        || (*defn_vec_ptr == IDL_DT_V1_STRING) )
1200    {
1201        /* Arrays of strings have a special representation */
1202        dimensionality--;
1203    }
1204
1205    /*
1206     * Z_value for each dimension of the array represents the size (bounds) of the array.
1207     * If Z_value is equal to upper - lower, then its a contiguous array
1208     * example: Z_value = 5, upper = 5, lower = 0 array elements 0, 1, 2, 3, 4
1209     * If Z_value is > than upper - lower, then its a non contigous array
1210     * example: Z_value = 10, upper = 10, lower = 0 array elements 0, 1, 2, 7, 8, 9
1211     */
1212    if (Z_values != NULL)   /* NULL possible for transmit_as case */
1213    {
1214        for (i = 0; i < dimensionality; i++)
1215        {
1216            if (range_list[i].upper < range_list[i].lower)
1217            {
1218                /* Upper should never be less than lower. */
1219                DCETHREAD_RAISE(rpc_x_invalid_bound);
1220            }
1221
1222            if (((unsigned32)(range_list[i].upper) > Z_values[i])
1223                || ((unsigned32)(range_list[i].lower) > Z_values[i]))
1224            {
1225                /* Upper and lower should never be greater than Z_values. */
1226                DCETHREAD_RAISE(rpc_x_invalid_bound);
1227            }
1228
1229            /* TO DO - Add more Z_values checks before we call this function <8767011> */
1230
1231            if ((unsigned32)(range_list[i].upper - range_list[i].lower) > Z_values[i])
1232            {
1233                /* Bogus data stream with A, B values outside of Z bound value */
1234                DCETHREAD_RAISE(rpc_x_invalid_bound);
1235            }
1236        }
1237    }
1238    for (i = 0; (unsigned32) i < dimensionality; i++)
1239    {
1240        if (range_list[i].upper == range_list[i].lower)
1241        {
1242            /* No elements to unmarshall */
1243            return;
1244        }
1245    }
1246
1247    rpc_ss_ndr_arr_align_and_opt( IDL_unmarshalling_k, dimensionality,
1248                                  &base_type, defn_vec_ptr,
1249                                  &unmarshall_by_copying, IDL_msp );
1250
1251    if (base_type == IDL_DT_REF_PTR)
1252    {
1253        /* Arrays of [ref] pointers are not marshalled */
1254        return;
1255    }
1256
1257    if ( (base_type == IDL_DT_STRING)
1258        || (base_type == IDL_DT_V1_STRING) )
1259    {
1260        /* Arrays of strings have a special representation */
1261        rpc_ss_get_string_base_desc( defn_vec_ptr, &element_size,
1262                                        &element_defn_index, IDL_msp );
1263    }
1264    else
1265        element_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
1266
1267    if (unmarshall_by_copying)
1268    {
1269        copy_addr = array_addr;
1270        rpc_ss_ndr_contiguous_elt( dimensionality, Z_values, range_list,
1271                       element_size, &contiguous, &element_count, &copy_addr );
1272        if (contiguous)
1273        {
1274            if (base_type == IDL_DT_FIXED_STRUCT)
1275            {
1276                /* There is a problem because for the last element of the
1277                structure we may not want to unmarshall sizeof(struct) bytes */
1278                element_count--;        /* So do the last one separately */
1279            }
1280            if (element_count != 0)
1281            {
1282                rpc_ss_ndr_unmar_by_copying( element_count, element_size,
1283                                         copy_addr, IDL_msp );
1284
1285                /* If it is a string, make sure its null terminated */
1286                if (flags & IDL_M_IS_STRING) {
1287                    /* point to start of last element */
1288                    cptr = copy_addr;
1289                    cptr += (element_count * element_size) - element_size;
1290                    /* (element_size) number of bytes should be 0 */
1291                    for (i = 0; i < element_size; i++, cptr++) {
1292                        if (*cptr != 0x00) {
1293                            DCETHREAD_RAISE(rpc_x_protocol_error);
1294                        }
1295                    }
1296                }
1297            }
1298            if (base_type == IDL_DT_FIXED_STRUCT)
1299            {
1300                /* Marshall the last element separately */
1301                defn_vec_ptr += 4;  /* See comment below */
1302                IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1303                rpc_ss_ndr_unmar_struct(base_type,
1304                                    IDL_msp->IDL_type_vec + element_defn_index,
1305                                    (rpc_void_p_t)((idl_byte *)copy_addr
1306                                                + element_count * element_size),
1307                                    NULL, NULL, IDL_msp);
1308            }
1309            return;
1310        }
1311    }
1312
1313    if ( (base_type == IDL_DT_FIXED_STRUCT)
1314         || (base_type == IDL_DT_ENC_UNION)
1315         || (base_type == IDL_DT_TRANSMIT_AS)
1316         || (base_type == IDL_DT_REPRESENT_AS) )
1317    {
1318        /* Discard any of DT_MODIFIED, type, modifier, properties
1319            which may be present, and any filler bytes */
1320        defn_vec_ptr += 4;
1321        IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1322    }
1323
1324    if (dimensionality > IDL_NORMAL_DIMS)
1325    {
1326        control_data = (IDL_varying_control_t *)rpc_ss_mem_alloc(
1327                            &IDL_msp->IDL_mem_handle,
1328                            dimensionality * sizeof(IDL_varying_control_t));
1329    }
1330    else
1331        control_data = normal_control_data;
1332    control_data[dimensionality-1].subslice_size = element_size;
1333    control_data[dimensionality-1].index_value =
1334                                            range_list[dimensionality-1].lower;
1335
1336    if (dimensionality >= 2)
1337    {
1338        for (i = dimensionality - 2; i >= 0; i--)
1339        {
1340            control_data[i].index_value = range_list[i].lower;
1341            assert (Z_values != NULL);
1342            control_data[i].subslice_size = control_data[i+1].subslice_size
1343                                                                * Z_values[i+1];
1344        }
1345    }
1346
1347    do {
1348        inner_slice_address = (idl_byte *)array_addr;
1349        for (i = 0; (unsigned32)i < dimensionality; i++)
1350        {
1351            inner_slice_address += control_data[i].index_value
1352                                        * control_data[i].subslice_size;
1353        }
1354        rpc_ss_ndr_unmar_by_looping(
1355                 range_list[dimensionality-1].upper
1356                                         - range_list[dimensionality-1].lower,
1357                 base_type, (rpc_void_p_t)inner_slice_address,
1358                 element_size, element_defn_index, IDL_msp);
1359
1360        dim = dimensionality - 2;
1361        while (dim >= 0)
1362        {
1363            control_data[dim].index_value++;
1364            if (control_data[dim].index_value < (unsigned32)range_list[dim].upper)
1365                break;
1366            control_data[dim].index_value = range_list[dim].lower;
1367            dim--;
1368        }
1369    } while (dim >= 0);
1370
1371    if (dimensionality > IDL_NORMAL_DIMS)
1372        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)control_data);
1373}
1374
1375/******************************************************************************/
1376/*                                                                            */
1377/*  Unmarshall the Z values for a conformant or open array                    */
1378/*                                                                            */
1379/******************************************************************************/
1380void rpc_ss_ndr_unmar_Z_values
1381(
1382    /* [in] */  idl_ulong_int dimensionality,
1383    /* [out] */ idl_ulong_int **p_Z_values,
1384    IDL_msp_t IDL_msp
1385)
1386{
1387    idl_ulong_int *Z_values;
1388    unsigned32 i;
1389
1390    if (*p_Z_values == NULL)
1391    {
1392        Z_values = (idl_ulong_int *)rpc_ss_mem_alloc(&IDL_msp->IDL_mem_handle,
1393                                        dimensionality * sizeof(idl_ulong_int));
1394        *p_Z_values = Z_values;
1395    }
1396    else
1397        Z_values = *p_Z_values;
1398
1399    for (i=0; i<dimensionality; i++)
1400    {
1401        IDL_UNMAR_ULONG( &Z_values[i] );
1402    }
1403}
1404
1405/******************************************************************************/
1406/*                                                                            */
1407/*  Unmarshall a varying array                                                */
1408/*                                                                            */
1409/******************************************************************************/
1410void rpc_ss_ndr_unmar_varying_arr
1411(
1412    /* [in] */ idl_byte *array_defn_ptr,
1413                                       /* On entry, points at dimensionality */
1414    /* [in] */ idl_boolean type_has_pointers,
1415    /* [in] */ rpc_void_p_t param_addr,
1416    /* [in] */ idl_ulong_int flags,
1417    IDL_msp_t IDL_msp
1418)
1419{
1420    idl_ulong_int array_dims;
1421    IDL_bound_pair_t *bounds_list;
1422    idl_ulong_int *Z_values;
1423    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
1424    IDL_bound_pair_t *range_list;
1425    IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS];
1426
1427    array_dims = (idl_ulong_int)*array_defn_ptr;
1428    array_defn_ptr++;
1429    /* By design array_defn_ptr is now at (0 mod 4) */
1430    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1431      rpc_ss_fixed_bounds_from_vector(array_dims, array_defn_ptr, &bounds_list,
1432				      IDL_msp);
1433    else
1434      bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
1435    if (array_dims > IDL_NORMAL_DIMS)
1436    {
1437        Z_values = NULL;
1438        range_list = NULL;
1439    }
1440    else
1441    {
1442        Z_values = normal_Z_values;
1443        range_list = normal_range_list;
1444    }
1445    rpc_ss_Z_values_from_bounds( bounds_list, array_dims, &Z_values, IDL_msp );
1446
1447    array_defn_ptr += array_dims * IDL_FIXED_BOUND_PAIR_WIDTH;
1448
1449    rpc_ss_ndr_unmar_range_list( array_dims,
1450       array_defn_ptr[array_dims * IDL_DATA_LIMIT_PAIR_WIDTH],
1451       &range_list, IDL_msp );
1452
1453    /* Check correlation and advance it to point at base type info */
1454    rpc_ss_ndr_unmar_check_range_correlation( &array_defn_ptr,
1455                             param_addr,
1456                             NULL,
1457                             NULL,
1458                             array_dims,
1459                             bounds_list,
1460                             range_list,
1461                             IDL_msp );
1462    if ( type_has_pointers && (IDL_msp->IDL_side == IDL_server_side_k) )
1463    {
1464        rpc_ss_init_new_array_ptrs( array_dims, Z_values,
1465                                      array_defn_ptr, param_addr, IDL_msp );
1466    }
1467    rpc_ss_ndr_u_var_or_open_arr( array_dims, Z_values,
1468                                  array_defn_ptr, param_addr,
1469                                  range_list, flags, IDL_msp );
1470    if (type_has_pointers)
1471    {
1472        /* By design array_defn_ptr is now at (0 mod 4) */
1473        rpc_ss_ndr_u_v_or_o_arr_ptees( array_dims, Z_values,
1474                                       array_defn_ptr, param_addr,
1475                                       range_list, IDL_msp );
1476    }
1477    if (array_dims > IDL_NORMAL_DIMS)
1478    {
1479        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)range_list);
1480        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1481    }
1482    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1483      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1484}
1485
1486/******************************************************************************/
1487/*                                                                            */
1488/*  Allocate an [out]-only conformant/open array                              */
1489/*                                                                            */
1490/******************************************************************************/
1491static void rpc_ss_alloc_out_conf_array
1492(
1493    /* [in,out] */ idl_byte **p_type_vec_ptr,
1494                   /* Pointer to type vec pointer, which this routine updates */
1495    /* [out] */ rpc_void_p_t *p_array_addr,
1496                   /* Where to return address of allocated array */
1497    /* [in,out] */ idl_ulong_int *p_num_conf_char_arrays
1498	 ATTRIBUTE_UNUSED,
1499                                         /* Number of conformant char arrays */
1500    IDL_msp_t IDL_msp
1501)
1502{
1503    idl_byte *type_vec_ptr = *p_type_vec_ptr;
1504    IDL_bound_pair_t *bounds_list;
1505    IDL_bound_pair_t normal_bounds_list[IDL_NORMAL_DIMS];
1506    idl_byte array_type;        /* DT_CONF_ARRAY or DT_OPEN_ARRAY */
1507    idl_boolean type_has_pointers;
1508    idl_ulong_int array_defn_index;
1509    idl_byte *array_defn_ptr;
1510    idl_ulong_int dimensionality;
1511    idl_ulong_int *Z_values;
1512    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
1513    idl_boolean is_string;
1514
1515    array_type = *type_vec_ptr;
1516    type_vec_ptr++;
1517    is_string = (array_type == IDL_DT_STRING);
1518    if ( is_string || (array_type == IDL_DT_V1_ARRAY) )
1519    {
1520        /* Get array type following qualifier */
1521        array_type = *type_vec_ptr;
1522        type_vec_ptr++;
1523    }
1524    /* Properties byte */
1525    type_has_pointers = IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1526    type_vec_ptr++;
1527    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1528                                            /* Discard full array definition */
1529    IDL_GET_LONG_FROM_VECTOR(array_defn_index,type_vec_ptr);
1530    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1531    dimensionality = (idl_ulong_int)*array_defn_ptr;
1532    array_defn_ptr++;
1533    if (dimensionality > IDL_NORMAL_DIMS)
1534    {
1535        bounds_list = NULL;
1536        Z_values = NULL;
1537    }
1538    else
1539    {
1540        bounds_list = normal_bounds_list;
1541        Z_values = normal_Z_values;
1542    }
1543    rpc_ss_build_bounds_list( &array_defn_ptr, NULL, NULL, NULL, dimensionality,
1544                              &bounds_list, IDL_msp );
1545    rpc_ss_Z_values_from_bounds( bounds_list, dimensionality, &Z_values,
1546                                                                   IDL_msp );
1547    if (array_type == IDL_DT_OPEN_ARRAY)
1548    {
1549        /* Ignore the "varying" information */
1550        array_defn_ptr += dimensionality * IDL_DATA_LIMIT_PAIR_WIDTH;
1551    }
1552    rpc_ss_ndr_alloc_storage( 0, dimensionality, Z_values, array_defn_ptr,
1553                              p_array_addr,
1554                              IDL_msp );
1555
1556    if (type_has_pointers)
1557    {
1558        rpc_ss_init_new_array_ptrs( dimensionality, Z_values, array_defn_ptr,
1559                                    *p_array_addr, IDL_msp );
1560    }
1561
1562    if (dimensionality > IDL_NORMAL_DIMS)
1563    {
1564        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1565        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1566    }
1567    *p_type_vec_ptr = type_vec_ptr;
1568}
1569
1570/******************************************************************************/
1571/*                                                                            */
1572/*  Control for unmarshalling                                                 */
1573/*                                                                            */
1574/******************************************************************************/
1575void rpc_ss_ndr_unmar_interp
1576(
1577    idl_ulong_int IDL_parameter_count, /* [in] -- Number of parameters to   */
1578                                  /* marshall in this call to the           */
1579                                  /* interpreter                            */
1580
1581    idl_ulong_int IDL_type_index,    /* [in] -- Offset into the type vector */
1582                                  /* for the description of the type to be  */
1583                                  /* marshalled                             */
1584
1585    rpc_void_p_t IDL_param_vector[], /* [in,out] -- The addresses of each of */
1586                                  /* the the parameters thus it's size is   */
1587                                  /* the number of parameters in the        */
1588                                  /* signature of the operation             */
1589
1590    IDL_msp_t IDL_msp        /* [in,out] -- Pointer to marshalling state   */
1591)
1592{
1593    idl_byte *type_vec_ptr;
1594    idl_byte type_byte;
1595    idl_ulong_int param_index;
1596    rpc_void_p_t param_addr;
1597    rpc_void_p_t *p_param_addr;
1598    idl_ulong_int defn_index;
1599    idl_boolean type_has_pointers;
1600    idl_boolean is_string = idl_false;
1601    idl_byte *struct_defn_ptr;
1602    idl_ulong_int offset_index;
1603#if 0
1604    idl_ulong_int rtn_index, iid_index;
1605#endif
1606    idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */
1607    idl_ulong_int array_defn_index;
1608    idl_byte *array_defn_ptr;
1609    idl_ulong_int conf_dims;    /* Number of dimensions of conformance info */
1610    idl_ulong_int *Z_values = NULL;
1611    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
1612    IDL_bound_pair_t *range_list;
1613    IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS];
1614    IDL_bound_pair_t *bounds_list;
1615    IDL_bound_pair_t range_bounds;
1616    IDL_bound_pair_t *correl_bounds_list;
1617    IDL_bound_pair_t normal_correl_bounds_list[IDL_NORMAL_DIMS];
1618    idl_ulong_int array_dims;   /* Number of dimensions of array */
1619    idl_ulong_int unique_flag;  /* Wire form of [unique] pointer */
1620    idl_byte *pointee_defn_ptr;
1621    IDL_pointee_desc_t pointee_desc;    /* Description of pointee */
1622    idl_ulong_int switch_value;     /* Discriminant of non-encapsulated union */
1623    intptr_t node_number = 0;
1624    idl_ushort_int v1_size;
1625    idl_ulong_int pseudo_Z_value;   /* v1 conformant size */
1626    idl_ulong_int num_conf_char_arrays; /* Number of conformant char arrays */
1627    idl_byte **conf_char_array_list = NULL;    /* List of pointers to type vec
1628                entries for conformant character arrays. Note that this list
1629                is only allocated if the language is FORTRAN. In this case
1630                it is written to for all parameters, but the list pointer
1631                is only advanced for conformant character arrays */
1632    IDL_cs_shadow_elt_t *param_cs_shadow = NULL;
1633                                         /* cs-shadow for the parameter list */
1634    idl_ulong_int param_shadow_length;
1635                                /* Length of the cs-shadow for parameter list */
1636    IDL_cs_shadow_elt_t *struct_cs_shadow;
1637                                    /* cs-shadow for the conformant structure */
1638    idl_ulong_int struct_shadow_length;
1639                        /* Length of the cs-shadow for a conformant structure */
1640
1641    IDL_INIT_RANGE( range_bounds );
1642
1643    if (IDL_msp->IDL_pickling_handle == NULL)
1644    {
1645        /* If pickling these variables are already set up */
1646        IDL_msp->IDL_mp = (idl_byte *)IDL_msp->IDL_elt_p->data_addr;
1647        IDL_msp->IDL_left_in_buff = IDL_msp->IDL_elt_p->data_len;
1648    }
1649
1650    num_conf_char_arrays = 0;
1651    if ((IDL_msp->IDL_language != IDL_lang_c_k)
1652        && (IDL_parameter_count != 0))
1653    {
1654        conf_char_array_list = (idl_byte **)rpc_ss_mem_alloc(
1655                                    &IDL_msp->IDL_mem_handle,
1656                                    IDL_parameter_count * sizeof(idl_byte *));
1657    }
1658
1659    /* Loop over parameters */
1660    type_vec_ptr = (IDL_msp->IDL_type_vec) + IDL_type_index;
1661    for ( ; IDL_parameter_count > 0; IDL_parameter_count -- )
1662    {
1663        if (IDL_msp->IDL_language != IDL_lang_c_k)
1664            conf_char_array_list[num_conf_char_arrays] = type_vec_ptr;
1665        IDL_GET_LONG_FROM_VECTOR(param_index,type_vec_ptr);
1666        param_addr = IDL_param_vector[param_index];
1667        do {
1668            type_byte = *type_vec_ptr;
1669            type_vec_ptr++;
1670            switch(type_byte)
1671            {
1672                case IDL_DT_BYTE:
1673                    IDL_UNMAR_BYTE( param_addr );
1674                    IDL_CHECK_RANGE_BYTE( range_bounds, param_addr );
1675                    break;
1676                case IDL_DT_CHAR:
1677                    IDL_UNMAR_CHAR( param_addr );
1678                    IDL_CHECK_RANGE_CHAR( range_bounds, param_addr );
1679                    break;
1680                case IDL_DT_BOOLEAN:
1681                    IDL_UNMAR_BOOLEAN( param_addr );
1682                    IDL_CHECK_RANGE_BOOLEAN( range_bounds, param_addr );
1683                    break;
1684                case IDL_DT_DOUBLE:
1685                    IDL_UNMAR_DOUBLE( param_addr );
1686                    IDL_CHECK_RANGE_DOUBLE( range_bounds, param_addr );
1687                    break;
1688                case IDL_DT_ENUM:
1689                    IDL_UNMAR_ENUM( param_addr );
1690                    break;
1691                case IDL_DT_FLOAT:
1692                    IDL_UNMAR_FLOAT( param_addr );
1693                    IDL_CHECK_RANGE_FLOAT( range_bounds, param_addr );
1694                    break;
1695                case IDL_DT_SMALL:
1696                    IDL_UNMAR_SMALL( param_addr );
1697                    IDL_CHECK_RANGE_SMALL( range_bounds, param_addr );
1698                    break;
1699                case IDL_DT_SHORT:
1700                    IDL_UNMAR_SHORT( param_addr );
1701                    IDL_CHECK_RANGE_SHORT( range_bounds, param_addr );
1702                    break;
1703                case IDL_DT_LONG:
1704                    IDL_UNMAR_LONG( param_addr );
1705                    IDL_CHECK_RANGE_LONG( range_bounds, param_addr );
1706                    break;
1707                case IDL_DT_HYPER:
1708                    IDL_UNMAR_HYPER( param_addr );
1709                    break;
1710                case IDL_DT_USMALL:
1711                    IDL_UNMAR_USMALL( param_addr );
1712                    IDL_CHECK_RANGE_USMALL( range_bounds, param_addr );
1713                    break;
1714                case IDL_DT_USHORT:
1715                    IDL_UNMAR_USHORT( param_addr );
1716                    IDL_CHECK_RANGE_USHORT( range_bounds, param_addr );
1717                    break;
1718                case IDL_DT_ULONG:
1719                    IDL_UNMAR_ULONG( param_addr );
1720                    IDL_CHECK_RANGE_ULONG( range_bounds, param_addr );
1721                    break;
1722                case IDL_DT_UHYPER:
1723                    IDL_UNMAR_UHYPER( param_addr );
1724                    break;
1725                case IDL_DT_V1_ENUM:
1726                    IDL_UNMAR_V1_ENUM( param_addr );
1727                    break;
1728                case IDL_DT_ERROR_STATUS:
1729                    IDL_UNMAR_ERROR_STATUS( param_addr );
1730                    break;
1731                case IDL_DT_FIXED_STRUCT:
1732                    /* Properties byte */
1733                    type_has_pointers =
1734                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1735                    type_vec_ptr++;
1736                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1737                    if ( type_has_pointers
1738                            && (IDL_msp->IDL_side == IDL_server_side_k) )
1739                    {
1740                        rpc_ss_init_new_struct_ptrs( type_byte,
1741                                            IDL_msp->IDL_type_vec+defn_index,
1742                                            param_addr, NULL, IDL_msp );
1743                    }
1744                    rpc_ss_ndr_unmar_struct(type_byte,
1745                                            IDL_msp->IDL_type_vec+defn_index,
1746                                            param_addr, NULL, NULL, IDL_msp);
1747                    if (type_has_pointers)
1748                    {
1749                        rpc_ss_ndr_u_struct_pointees(type_byte, defn_index,
1750                                                param_addr, Z_values, IDL_msp);
1751                    }
1752                    break;
1753                case IDL_DT_CONF_STRUCT:
1754                case IDL_DT_V1_CONF_STRUCT:
1755                    /* Properties byte */
1756                    type_has_pointers =
1757                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1758                    type_vec_ptr++;
1759                    IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr);
1760                    struct_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
1761                    IDL_GET_LONG_FROM_VECTOR(offset_index,struct_defn_ptr);
1762                    struct_offset_vec_ptr = IDL_msp->IDL_offset_vec
1763                                                                 + offset_index;
1764                    IDL_GET_LONG_FROM_VECTOR(array_defn_index,struct_defn_ptr);
1765                    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1766                    if (*struct_defn_ptr == IDL_DT_CS_SHADOW)
1767                    {
1768                        struct_defn_ptr++;
1769                        IDL_GET_LONG_FROM_VECTOR(struct_shadow_length,
1770                                                            struct_defn_ptr);
1771                        struct_cs_shadow = (IDL_cs_shadow_elt_t *)
1772                                            rpc_ss_mem_alloc
1773                                             (&IDL_msp->IDL_mem_handle,
1774                                              struct_shadow_length *
1775                                                sizeof(IDL_cs_shadow_elt_t));
1776                    }
1777                    else
1778                        struct_cs_shadow = NULL;
1779                    conf_dims = (idl_ulong_int)*array_defn_ptr;
1780                    array_defn_ptr++;
1781                    if (conf_dims > IDL_NORMAL_DIMS)
1782                        Z_values = NULL;
1783                    else
1784                        Z_values = normal_Z_values;
1785                    if (type_byte == IDL_DT_V1_CONF_STRUCT)
1786                    {
1787                        IDL_UNMAR_CUSHORT( &v1_size );
1788                        *Z_values = (idl_ulong_int)v1_size;
1789                    }
1790                    else
1791                        rpc_ss_ndr_unmar_Z_values( conf_dims, &Z_values,
1792                                                                     IDL_msp );
1793                    /* Skip over the bounds in the array defn
1794                                                 to get to the base type */
1795                    IDL_ADV_DEFN_PTR_OVER_BOUNDS( array_defn_ptr, conf_dims );
1796                    if (*array_defn_ptr == IDL_DT_CS_TYPE)
1797                    {
1798                        rpc_ss_ndr_u_conf_cs_struct_hdr(
1799                                    IDL_msp->IDL_type_vec + defn_index,
1800                                    array_defn_ptr - IDL_CONF_BOUND_PAIR_WIDTH,
1801                                    Z_values, *struct_offset_vec_ptr,
1802                                    type_has_pointers,
1803                                    struct_shadow_length - 1,
1804                                    IDL_msp->IDL_side == IDL_server_side_k,
1805                                    struct_cs_shadow,
1806                                    &IDL_param_vector[param_index], IDL_msp);
1807                    }
1808                    else
1809                    {
1810                        if (IDL_msp->IDL_side == IDL_server_side_k)
1811                        {
1812                            if (type_byte == IDL_DT_V1_CONF_STRUCT)
1813                                rpc_ss_ndr_alloc_storage(*struct_offset_vec_ptr,
1814                                    1, Z_values, array_defn_ptr,
1815                                    &IDL_param_vector[param_index], IDL_msp);
1816                            else
1817                                rpc_ss_ndr_alloc_storage(*struct_offset_vec_ptr,
1818                                    conf_dims, Z_values, array_defn_ptr,
1819                                    &IDL_param_vector[param_index], IDL_msp);
1820                            if (type_has_pointers)
1821                            {
1822                                rpc_ss_init_new_struct_ptrs( type_byte,
1823                                            IDL_msp->IDL_type_vec+defn_index,
1824                                            IDL_param_vector[param_index],
1825                                            Z_values, IDL_msp);
1826                            }
1827                        }
1828                    }
1829                    rpc_ss_ndr_unmar_struct(type_byte,
1830                                            IDL_msp->IDL_type_vec+defn_index,
1831                                             IDL_param_vector[param_index],
1832                                             Z_values, struct_cs_shadow,
1833                                             IDL_msp);
1834                    if (type_has_pointers)
1835                    {
1836                        rpc_ss_ndr_u_struct_pointees(type_byte, defn_index,
1837                                 IDL_param_vector[param_index],
1838                                 Z_values, IDL_msp);
1839                    }
1840                    if (conf_dims > IDL_NORMAL_DIMS)
1841                        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1842                                                (byte_p_t)Z_values);
1843                    break;
1844                case IDL_DT_FIXED_ARRAY:
1845                    /* Properties byte */
1846                    type_has_pointers =
1847                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1848                    type_vec_ptr++;
1849                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1850                                            /* Discard full array definition */
1851                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1852                    if ( type_has_pointers
1853                            && (IDL_msp->IDL_side == IDL_server_side_k) )
1854                    {
1855                        array_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
1856                        array_dims = (idl_ulong_int)*array_defn_ptr;
1857                        array_defn_ptr++;
1858                        /* By design array_defn_ptr is now at (0 mod 4) */
1859			if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] !=
1860			    NDR_LOCAL_INT_REP)
1861			  rpc_ss_fixed_bounds_from_vector(array_dims,
1862							  array_defn_ptr,
1863							  &bounds_list,
1864							  IDL_msp);
1865			else
1866			  bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
1867                        /* Advance it to point at base type info */
1868                        array_defn_ptr += array_dims
1869                                                 * IDL_FIXED_BOUND_PAIR_WIDTH;
1870                        if (array_dims > IDL_NORMAL_DIMS)
1871                            Z_values = NULL;
1872                        else
1873                            Z_values = normal_Z_values;
1874                        rpc_ss_Z_values_from_bounds( bounds_list, array_dims,
1875                                                           &Z_values, IDL_msp );
1876                        rpc_ss_init_new_array_ptrs( array_dims, Z_values,
1877                                          array_defn_ptr, param_addr, IDL_msp );
1878                        if (array_dims > IDL_NORMAL_DIMS)
1879                            rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1880                                                            (byte_p_t)Z_values);
1881			if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] !=
1882			    NDR_LOCAL_INT_REP)
1883			  rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1884                                                         (byte_p_t)bounds_list);
1885                    }
1886                    rpc_ss_ndr_unmar_fixed_arr(defn_index, param_addr,
1887                                               IDL_M_IS_PARAM, IDL_msp);
1888                    if (type_has_pointers)
1889                    {
1890                        rpc_ss_ndr_u_fixed_arr_ptees(defn_index, param_addr,
1891                                                                       IDL_msp);
1892                    }
1893                    break;
1894                case IDL_DT_VARYING_ARRAY:
1895                    /* Properties byte */
1896                    type_has_pointers = IDL_PROP_TEST(*type_vec_ptr,
1897                                                             IDL_PROP_HAS_PTRS);
1898                    type_vec_ptr++;
1899                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1900                                            /* Discard full array definition */
1901                    IDL_GET_LONG_FROM_VECTOR(array_defn_index, type_vec_ptr);
1902                    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1903                    rpc_ss_ndr_unmar_varying_arr( array_defn_ptr,
1904                             type_has_pointers, param_addr,
1905                             IDL_M_IS_PARAM | (is_string ? IDL_M_IS_STRING : 0),
1906                             IDL_msp );
1907                    is_string = idl_false;
1908                    break;
1909                case IDL_DT_CONF_ARRAY:
1910                    /* Properties byte */
1911                    type_has_pointers =
1912                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1913                    type_vec_ptr++;
1914                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1915                                            /* Discard full array definition */
1916                    IDL_GET_LONG_FROM_VECTOR(array_defn_index,type_vec_ptr);
1917                    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1918                    conf_dims = (idl_ulong_int)*array_defn_ptr;
1919                    array_defn_ptr++;
1920                    if (conf_dims > IDL_NORMAL_DIMS)
1921                        Z_values = NULL;
1922                    else
1923                        Z_values = normal_Z_values;
1924                    rpc_ss_ndr_unmar_Z_values( conf_dims, &Z_values, IDL_msp );
1925                    rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr,
1926                                             &IDL_param_vector[param_index],
1927                                             NULL,
1928                                             NULL,
1929                                             conf_dims,
1930                                             Z_values,
1931                                             FALSE,
1932                                             NULL,
1933                                             IDL_msp );
1934                    if (IDL_msp->IDL_side == IDL_server_side_k)
1935                    {
1936                        p_param_addr = &IDL_param_vector[param_index];
1937                        rpc_ss_ndr_alloc_storage( 0, conf_dims, Z_values,
1938                                                 array_defn_ptr, p_param_addr,
1939                                                 IDL_msp );
1940                        if (type_has_pointers)
1941                        {
1942                            rpc_ss_init_new_array_ptrs( conf_dims, Z_values,
1943                                                 array_defn_ptr,
1944                                                 IDL_param_vector[param_index],
1945                                                 IDL_msp );
1946                        }
1947                    }
1948                    rpc_ss_ndr_u_fix_or_conf_arr( conf_dims, Z_values,
1949                                              array_defn_ptr,
1950                                              IDL_param_vector[param_index],
1951                                              IDL_M_IS_PARAM | IDL_M_CONF_ARRAY,
1952                                              IDL_msp );
1953                    if (type_has_pointers)
1954                    {
1955                        rpc_ss_ndr_u_f_or_c_arr_ptees( conf_dims, Z_values,
1956                                                 array_defn_ptr,
1957                                                 IDL_param_vector[param_index],
1958                                                 IDL_msp );
1959                    }
1960                    if (conf_dims > IDL_NORMAL_DIMS)
1961                        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1962                                                (byte_p_t)Z_values);
1963                    break;
1964                case IDL_DT_OPEN_ARRAY:
1965                    /* Properties byte */
1966                    type_has_pointers =
1967                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1968                    type_vec_ptr++;
1969                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1970                                            /* Discard full array definition */
1971                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1972                    array_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
1973                    conf_dims = (idl_ulong_int)*array_defn_ptr;
1974                    array_defn_ptr++;
1975                    if (conf_dims > IDL_NORMAL_DIMS)
1976                    {
1977                        Z_values = NULL;
1978                        correl_bounds_list = NULL;
1979                        range_list = NULL;
1980                    }
1981                    else
1982                    {
1983                        range_list = normal_range_list;
1984                        Z_values = normal_Z_values;
1985                        correl_bounds_list = normal_correl_bounds_list;
1986                    }
1987                    rpc_ss_ndr_unmar_Z_values( conf_dims, &Z_values, IDL_msp );
1988                    /* Check correlation and advance array_defn_ptr over data limit info */
1989                    rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr,
1990                                             &IDL_param_vector[param_index],
1991                                             NULL,
1992                                             NULL,
1993                                             conf_dims,
1994                                             Z_values,
1995                                             FALSE,
1996                                             &correl_bounds_list,
1997                                             IDL_msp );
1998                    rpc_ss_ndr_unmar_range_list( conf_dims,
1999                                             array_defn_ptr[conf_dims * IDL_DATA_LIMIT_PAIR_WIDTH],
2000                                             &range_list, IDL_msp );
2001                    rpc_ss_ndr_unmar_check_range_correlation( &array_defn_ptr,
2002                                             &IDL_param_vector[param_index],
2003                                             NULL,
2004                                             NULL,
2005                                             conf_dims,
2006                                             correl_bounds_list,
2007                                             range_list,
2008                                             IDL_msp );
2009                    if (IDL_msp->IDL_side == IDL_server_side_k)
2010                    {
2011                        p_param_addr = &IDL_param_vector[param_index];
2012                        rpc_ss_ndr_alloc_storage( 0, conf_dims, Z_values,
2013                                                 array_defn_ptr, p_param_addr,
2014                                                 IDL_msp );
2015                        if (type_has_pointers)
2016                        {
2017                            rpc_ss_init_new_array_ptrs( conf_dims, Z_values,
2018                                                 array_defn_ptr,
2019                                                 IDL_param_vector[param_index],
2020                                                 IDL_msp );
2021                        }
2022                    }
2023                    rpc_ss_ndr_u_var_or_open_arr( conf_dims, Z_values,
2024                             array_defn_ptr, IDL_param_vector[param_index],
2025                             range_list, IDL_M_CONF_ARRAY | IDL_M_IS_PARAM
2026                                           | (is_string ? IDL_M_IS_STRING : 0),
2027                             IDL_msp );
2028                    if (type_has_pointers)
2029                    {
2030                        rpc_ss_ndr_u_v_or_o_arr_ptees( conf_dims, Z_values,
2031                                                 array_defn_ptr,
2032                                                 IDL_param_vector[param_index],
2033                                                 range_list, IDL_msp );
2034                    }
2035                    if (conf_dims > IDL_NORMAL_DIMS)
2036                    {
2037                        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2038                                                (byte_p_t)Z_values);
2039                        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2040                                                (byte_p_t)correl_bounds_list);
2041                        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2042                                                (byte_p_t)range_list);
2043                    }
2044                    is_string = idl_false;
2045                    break;
2046                case IDL_DT_ENC_UNION:
2047                    /* Properties byte */
2048                    type_has_pointers =
2049                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
2050                    type_vec_ptr++;
2051                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2052                    rpc_ss_ndr_u_enc_union_or_ptees( param_addr, defn_index,
2053                                                     idl_false, IDL_msp);
2054                    if (type_has_pointers)
2055                    {
2056                        rpc_ss_ndr_u_enc_union_or_ptees( param_addr, defn_index,
2057                                                         idl_true, IDL_msp);
2058                    }
2059                    break;
2060                case IDL_DT_N_E_UNION:
2061                    /* Properties byte */
2062                    type_has_pointers =
2063                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
2064                    type_vec_ptr++;
2065                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2066                                                     /* Discard switch index */
2067                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2068                    rpc_ss_ndr_unmar_n_e_union( param_addr, defn_index,
2069                                                     &switch_value, IDL_msp);
2070                    if (type_has_pointers)
2071                    {
2072                        rpc_ss_ndr_u_n_e_union_ptees( param_addr, switch_value,
2073                                            0, defn_index, NULL, NULL, IDL_msp);
2074                    }
2075                    break;
2076                case IDL_DT_PASSED_BY_REF:
2077                    break;
2078                case IDL_DT_FULL_PTR:
2079		{
2080	            idl_ulong_int _node;
2081                    type_vec_ptr++;     /* Properties byte */
2082                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2083                    /* Unmarshall the node number */
2084                    IDL_UNMAR_ULONG( &_node );
2085		    node_number = (intptr_t) _node;
2086                    *(rpc_void_p_t *)(IDL_param_vector[param_index])
2087                                                    = (rpc_void_p_t)node_number;
2088                    if (node_number != 0)
2089                    {
2090                        pointee_defn_ptr = IDL_msp->IDL_type_vec+defn_index;
2091                        pointee_desc.dimensionality = 0;
2092                        pointee_desc.struct_addr = NULL;
2093                        pointee_desc.struct_offset_vec_ptr = NULL;
2094                        rpc_ss_ndr_unmar_pointee_desc( type_byte,
2095                                                pointee_defn_ptr,
2096                                                &pointee_desc,
2097                                                IDL_param_vector[param_index],
2098                                                IDL_msp );
2099                        rpc_ss_ndr_unmar_pointee( type_byte,
2100                                                pointee_defn_ptr,
2101                                                &pointee_desc,
2102                                                IDL_param_vector[param_index],
2103                                                IDL_msp );
2104                        rpc_ss_ndr_u_rlse_pointee_desc(&pointee_desc, IDL_msp);
2105                    }
2106                    break;
2107		}
2108                case IDL_DT_UNIQUE_PTR:
2109                    type_vec_ptr++;     /* Properties byte */
2110                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2111                    IDL_UNMAR_ULONG( &unique_flag );
2112                    if (unique_flag == 0)
2113                    {
2114                        *(rpc_void_p_t *)(IDL_param_vector[param_index])
2115                                                                         = NULL;
2116                    }
2117                    else
2118                    {
2119                        pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
2120                        pointee_desc.dimensionality = 0;
2121                        pointee_desc.struct_addr = NULL;
2122                        pointee_desc.struct_offset_vec_ptr = NULL;
2123                        rpc_ss_ndr_unmar_pointee_desc( type_byte,
2124                                                pointee_defn_ptr,
2125                                                &pointee_desc,
2126                                                IDL_param_vector[param_index],
2127                                                IDL_msp );
2128                        if ((IDL_msp->IDL_side == IDL_server_side_k)
2129                           || (*(rpc_void_p_t *)(IDL_param_vector[param_index])
2130                                                                       == NULL))
2131                        {
2132                            *(rpc_void_p_t *)(IDL_param_vector[param_index])
2133                                                                 = IDL_NEW_NODE;
2134                        }
2135                        rpc_ss_ndr_unmar_pointee( type_byte, pointee_defn_ptr,
2136                                                &pointee_desc,
2137                                                IDL_param_vector[param_index],
2138                                                IDL_msp );
2139                        rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc,
2140                                                                IDL_msp );
2141                    }
2142                    break;
2143                case IDL_DT_REF_PTR:
2144                    type_vec_ptr++;     /* Properties byte */
2145                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2146                    pointee_defn_ptr = IDL_msp->IDL_type_vec+defn_index;
2147                    if (IDL_msp->IDL_side == IDL_server_side_k)
2148                    {
2149                        rpc_ss_alloc_pointer_target(pointee_defn_ptr,
2150                                               IDL_param_vector[param_index],
2151                                               IDL_msp );
2152                    }
2153                    pointee_desc.dimensionality = 0;
2154                    pointee_desc.struct_addr = NULL;
2155                    pointee_desc.struct_offset_vec_ptr = NULL;
2156                    rpc_ss_ndr_unmar_pointee_desc( type_byte, pointee_defn_ptr,
2157                                                &pointee_desc,
2158                                                IDL_param_vector[param_index],
2159                                                IDL_msp );
2160                    rpc_ss_ndr_unmar_pointee( type_byte, pointee_defn_ptr,
2161                                                &pointee_desc,
2162                                                IDL_param_vector[param_index],
2163                                                IDL_msp );
2164                    rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp );
2165                    break;
2166                case IDL_DT_STRING:
2167                    /* Varying/open array code will do the right thing */
2168                    is_string = idl_true;
2169                    break;
2170                case IDL_DT_TRANSMIT_AS:
2171                case IDL_DT_REPRESENT_AS:
2172                    type_vec_ptr++;     /* Properties byte */
2173                    IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr);
2174                    rpc_ss_ndr_unmar_xmit_as(defn_index,
2175                                             IDL_param_vector[param_index],
2176                                             NULL, IDL_msp );
2177                    break;
2178#if 0
2179                case IDL_DT_INTERFACE:
2180                    type_vec_ptr++;     /* Properties byte */
2181                    IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr);
2182                    rpc_ss_ndr_unmar_interface(defn_index,
2183                        		       IDL_param_vector[param_index],
2184                        		       NULL, IDL_msp );
2185                   break;
2186                case IDL_DT_DYN_INTERFACE:
2187                    type_vec_ptr++;     /* Properties byte */
2188                    IDL_GET_LONG_FROM_VECTOR(rtn_index, type_vec_ptr);
2189                    IDL_GET_LONG_FROM_VECTOR(iid_index, type_vec_ptr);
2190                    rpc_ss_ndr_unmar_dyn_interface(rtn_index,
2191                        		       IDL_param_vector[param_index],
2192                        		       ((idl_uuid_t *) IDL_param_vector[iid_index]),
2193                        		       NULL, IDL_msp );
2194                   break;
2195#endif
2196                case IDL_DT_ALLOCATE:
2197                    /* Indicates an [out]-only conformant or open array must
2198                        be allocated. Should only appear on server side */
2199                    rpc_ss_alloc_out_conf_array( &type_vec_ptr,
2200                                                 &IDL_param_vector[param_index],
2201                                                 &num_conf_char_arrays,
2202                                                 IDL_msp );
2203                    break;
2204                case IDL_DT_ALLOCATE_REF:
2205                    /* Indicates that the pointees of [ref] pointers in an [out]
2206                        only parameter must be allocated. Should only appear
2207                        on server side */
2208                    rpc_ss_init_out_ref_ptrs( &type_vec_ptr, param_addr,
2209                                                                     IDL_msp );
2210                    break;
2211                case IDL_DT_PIPE:
2212                    if (IDL_msp->IDL_side == IDL_server_side_k)
2213                    {
2214                        /* Rest of unmarshalling is done by manager calls */
2215                        return;
2216                    }
2217                    else
2218                    {
2219                        type_vec_ptr++;     /* Properties byte */
2220                        IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2221                        rpc_ss_ndr_unmar_pipe(defn_index, param_addr, IDL_msp);
2222                    }
2223                    break;
2224                case IDL_DT_IN_CONTEXT:
2225                case IDL_DT_IN_OUT_CONTEXT:
2226                case IDL_DT_OUT_CONTEXT:
2227                    rpc_ss_ndr_unmar_context(type_byte, param_addr, IDL_msp);
2228                    break;
2229                case IDL_DT_V1_ARRAY:
2230                    type_byte = *type_vec_ptr;  /* DT_VARYING or DT_OPEN */
2231                    type_vec_ptr += 2;       /* Skip over properties byte */
2232                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2233                                            /* Discard full array definition */
2234                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2235                    array_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
2236                    array_dims = (idl_ulong_int)*array_defn_ptr;
2237                    array_defn_ptr++;
2238                    if (type_byte == IDL_DT_OPEN_ARRAY)
2239                    {
2240                        IDL_ADV_DEFN_PTR_OVER_BOUNDS( array_defn_ptr,
2241                                                                  array_dims );
2242                        /* Advance array_defn_ptr over data limit info */
2243                        array_defn_ptr += array_dims
2244                                                    * IDL_DATA_LIMIT_PAIR_WIDTH;
2245                        IDL_UNMAR_CUSHORT( &v1_size );
2246                        if (IDL_msp->IDL_side == IDL_server_side_k)
2247                        {
2248                            pseudo_Z_value = (idl_ulong_int)v1_size;
2249                            rpc_ss_ndr_alloc_storage( 0, 1, &pseudo_Z_value,
2250                                                 array_defn_ptr,
2251                                                 &IDL_param_vector[param_index],
2252                                                 IDL_msp );
2253                        }
2254                    }
2255                    else    /* IDL_DT_VARYING_ARRAY */
2256                    {
2257                        array_defn_ptr += array_dims
2258                                             * (IDL_FIXED_BOUND_PAIR_WIDTH
2259                                                + IDL_DATA_LIMIT_PAIR_WIDTH);
2260                    }
2261                    rpc_ss_ndr_u_v1_varying_arr(IDL_param_vector[param_index],
2262                                                array_defn_ptr, IDL_M_IS_PARAM,
2263                                                IDL_msp );
2264                    break;
2265                case IDL_DT_V1_STRING:
2266                    type_vec_ptr += 2;  /* DT_VARYING_ARRAY and properties */
2267                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2268                                                        /* Full array defn */
2269                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2270                                                      /* Flattened array defn */
2271                    rpc_ss_ndr_unmar_v1_string(param_addr, IDL_M_IS_PARAM,
2272                                                                     IDL_msp);
2273                    break;
2274                case IDL_DT_FREE_REP:
2275                    /* Just needs skipping over */
2276                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2277                    break;
2278                case IDL_DT_DELETED_NODES:
2279                    rpc_ss_ndr_unmar_deletes(IDL_msp);
2280                    break;
2281                case IDL_DT_CS_SHADOW:
2282                    IDL_GET_LONG_FROM_VECTOR(param_shadow_length, type_vec_ptr);
2283                    param_cs_shadow = (IDL_cs_shadow_elt_t *)
2284                                            rpc_ss_mem_alloc
2285                                             (&IDL_msp->IDL_mem_handle,
2286                                              param_shadow_length *
2287                                                sizeof(IDL_cs_shadow_elt_t));
2288                    break;
2289                case IDL_DT_CS_ARRAY:
2290                    if (*type_vec_ptr == IDL_DT_ALLOCATE)
2291                    {
2292                        rpc_ss_alloc_out_cs_conf_array(param_cs_shadow,
2293                                                 &type_vec_ptr,
2294                                                 &IDL_param_vector[param_index],
2295                                                 IDL_msp);
2296                    }
2297                    else
2298                    {
2299                        rpc_ss_ndr_u_cs_array_param(&type_vec_ptr,
2300                                         param_cs_shadow, param_index, IDL_msp);
2301                    }
2302                    break;
2303                case IDL_DT_CS_ATTRIBUTE:
2304                    /* Unmarshall the parameter normally. It will get
2305                        overwritten later */
2306                    break;
2307                case IDL_DT_CS_TYPE:
2308                    type_vec_ptr++;     /* Properties byte */
2309                    IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr);
2310                    rpc_ss_ndr_unmar_cs_char(param_addr, defn_index, IDL_msp);
2311                    break;
2312                case IDL_DT_CS_RLSE_SHADOW:
2313                    rpc_ss_ndr_u_param_cs_shadow(
2314                                      IDL_type_index, param_cs_shadow, IDL_msp);
2315                    break;
2316                case IDL_DT_RANGE:
2317                    IDL_GET_RANGE_FROM_VECTOR(range_bounds, type_vec_ptr);
2318                    break;
2319                case IDL_DT_EOL:
2320                    break;
2321                default:
2322#ifdef DEBUG_INTERP
2323                    printf("rpc_ss_ndr_unmar_interp:unrecognized type %d\n",
2324                        type_byte);
2325                    exit(0);
2326#endif
2327                    DCETHREAD_RAISE(rpc_x_coding_error);
2328            }
2329        } while (type_byte != IDL_DT_EOL);
2330    }
2331    if ((IDL_msp->IDL_language != IDL_lang_c_k)
2332        && (IDL_parameter_count != 0))
2333    {
2334        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2335                                (byte_p_t)conf_char_array_list);
2336    }
2337
2338    if (IDL_msp->IDL_pickling_handle == NULL)
2339    {
2340        if (IDL_msp->IDL_elt_p->buff_dealloc
2341                    && IDL_msp->IDL_elt_p->data_len != 0)
2342            (*(IDL_msp->IDL_elt_p->buff_dealloc))
2343                                                (IDL_msp->IDL_elt_p->buff_addr);
2344        IDL_msp->IDL_elt_p = NULL;
2345    }
2346    else
2347    {
2348        /* For pickling, buffer was rounded out to a multiple of 8 bytes */
2349        IDL_UNMAR_ALIGN_MP(IDL_msp, 8);
2350    }
2351}
2352
2353/******************************************************************************/
2354/*                                                                            */
2355/*  Create a bitmap indicating which dimensions are determined from           */
2356/*  parameters or fields that occur before the struct or array definition     */
2357/*  itself.                                                                   */
2358/*                                                                            */
2359/******************************************************************************/
2360static void
2361rpc_ss_ndr_unmar_cf_early
2362(
2363    /* [in] */ idl_byte **p_defn_vec_ptr, /* if early, not modified */
2364                                          /* if late, points past bounds/limit info */
2365    /* [in] */ idl_ulong_int dimensionality, /* dimensionality of array */
2366    /* [in] */ idl_boolean pre_unmar,
2367    /* [out] */ idl_boolean **p_early_list,
2368    IDL_msp_t IDL_msp
2369)
2370{
2371    idl_ulong_int i;
2372    idl_byte *defn_vec_ptr = *p_defn_vec_ptr;
2373    idl_boolean *early_list;
2374
2375    if (*p_early_list == NULL)
2376    {
2377        early_list = (idl_boolean *)rpc_ss_mem_alloc
2378          (&IDL_msp->IDL_mem_handle, dimensionality * sizeof(idl_boolean));
2379    }
2380    else
2381        early_list = *p_early_list;
2382
2383    for (i = 0; i < dimensionality; i++)
2384    {
2385        idl_byte kind;
2386        idl_ulong_int attribute_index = 0;
2387        idl_boolean early;
2388
2389        kind = (*defn_vec_ptr & IDL_LIMIT_TYPE_MASK);
2390        early = !!(*defn_vec_ptr & IDL_CF_EARLY);
2391        defn_vec_ptr++;
2392
2393        early_list[i] = idl_true;
2394
2395        /* Get lower bound or limit */
2396        if (kind == IDL_LIMIT_FIXED)
2397        {
2398            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
2399        }
2400        else
2401        {
2402            defn_vec_ptr++;
2403            IDL_GET_LONG_FROM_VECTOR(attribute_index, defn_vec_ptr);
2404
2405            if (!early || pre_unmar)
2406            {
2407                early_list[i] = idl_false;
2408            }
2409        }
2410
2411        /* Get upper bound or limit */
2412        kind = (*defn_vec_ptr & IDL_LIMIT_TYPE_MASK);
2413        early = !!(*defn_vec_ptr & IDL_CF_EARLY);
2414        defn_vec_ptr++;
2415        if (kind == IDL_LIMIT_FIXED)
2416        {
2417            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
2418        }
2419        else
2420        {
2421            if (kind == IDL_LIMIT_LENGTH_IS)
2422                defn_vec_ptr++; /* discard function code */
2423
2424            defn_vec_ptr++;
2425            IDL_GET_LONG_FROM_VECTOR(attribute_index, defn_vec_ptr);
2426
2427            if ((kind != IDL_LIMIT_UPPER_CONF && !early) || pre_unmar)
2428            {
2429                early_list[i] = idl_false;
2430            }
2431        }
2432    }
2433
2434    /*
2435     * If all dimensions are determined by fields or parameters that
2436     * occur later, then return NULL and advance the definition pointer.
2437     */
2438    for (i = 0; i < dimensionality; i++)
2439    {
2440        if (early_list[i])
2441        {
2442            *p_early_list = early_list;
2443            return;
2444        }
2445    }
2446
2447    if (*p_early_list == NULL)
2448        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2449                             (byte_p_t)early_list);
2450
2451    *p_early_list = NULL;
2452
2453    /* Advance past bounds/limits */
2454    *p_defn_vec_ptr = defn_vec_ptr;
2455}
2456
2457/******************************************************************************/
2458/*                                                                            */
2459/*  Perform bounds correlation checking; only works for early bindings        */
2460/*                                                                            */
2461/******************************************************************************/
2462void rpc_ss_ndr_unmar_check_bounds_correlation
2463(
2464    /* [in] */ idl_byte **p_defn_vec_ptr,
2465    /* [in] */ rpc_void_p_t array_addr,
2466    /* [in] */ rpc_void_p_t struct_addr,
2467    /* [in] */ idl_ulong_int *struct_offset_vec_ptr,
2468    /* [in] */ idl_ulong_int dimensionality,
2469    /* [in] */ idl_ulong_int *Z_values,
2470    /* [in] */ idl_boolean pre_unmar,
2471    /* [out] */ IDL_bound_pair_t **p_correl_bounds_list,
2472    IDL_msp_t IDL_msp
2473)
2474{
2475    IDL_bound_pair_t *correl_bounds_list;
2476    IDL_bound_pair_t normal_correl_bounds_list[IDL_NORMAL_DIMS];
2477    idl_boolean *early_list;
2478    idl_boolean normal_early_list[IDL_NORMAL_DIMS];
2479    idl_ulong_int i;
2480    idl_boolean correl_ok = idl_true;
2481    idl_boolean free_correl_bounds_list = idl_false;
2482
2483    /*
2484     * If the correlated bounds are marshalled after the "NDR" bounds,
2485     * then correlation checking is only possible after unmarshalling.
2486     * This is not supported at present. To avoid attempting to read
2487     * uninitialized memory we simply return if the correlation is not
2488     * "early".
2489     *
2490     * Note: the following code assumes invariance between IDL_BOUND_
2491     * and IDL_LIMIT_. If you change these constants this will break.
2492     */
2493    if (dimensionality > IDL_NORMAL_DIMS)
2494        early_list = NULL;
2495    else
2496        early_list = normal_early_list;
2497
2498    rpc_ss_ndr_unmar_cf_early(p_defn_vec_ptr, dimensionality, pre_unmar,
2499                              &early_list, IDL_msp);
2500    if (early_list == NULL) {
2501        return;
2502    }
2503
2504    if (p_correl_bounds_list == NULL)
2505    {
2506        if (dimensionality > IDL_NORMAL_DIMS)
2507        {
2508            correl_bounds_list = NULL;
2509            free_correl_bounds_list = idl_true;
2510        }
2511        else
2512        {
2513            correl_bounds_list = normal_correl_bounds_list;
2514        }
2515
2516        p_correl_bounds_list = &correl_bounds_list;
2517    }
2518
2519    rpc_ss_build_bounds_list_2(p_defn_vec_ptr, array_addr, struct_addr,
2520                               struct_offset_vec_ptr, dimensionality,
2521                               early_list, p_correl_bounds_list,
2522                               IDL_msp);
2523
2524    for (i = 0; i < dimensionality; i++)
2525    {
2526        idl_ulong_int correl_Z_value;
2527        IDL_bound_pair_t *correl_bounds = &((*p_correl_bounds_list)[i]);
2528
2529        if (early_list[i] == idl_false)
2530            continue;
2531
2532        if (correl_bounds->upper >= correl_bounds->lower)
2533            correl_Z_value = correl_bounds->upper - correl_bounds->lower + 1;
2534        else
2535            correl_Z_value = 0;
2536
2537        if (Z_values[i] != correl_Z_value)
2538        {
2539#ifdef DEBUG_INTERP
2540            printf("rpc_ss_ndr_unmar_check_bounds_correlation: "
2541                   "Z_value correlation mismatch (%ld != %ld)\n",
2542                   correl_Z_value, Z_values[i]);
2543#endif
2544            correl_ok = idl_false;
2545            break;
2546        }
2547    }
2548
2549    if (free_correl_bounds_list)
2550        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2551                             (byte_p_t)correl_bounds_list);
2552
2553    if (dimensionality > IDL_NORMAL_DIMS)
2554        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2555                             (byte_p_t)early_list);
2556
2557    if (correl_ok == idl_false)
2558        DCETHREAD_RAISE( rpc_x_invalid_bound );
2559}
2560
2561/******************************************************************************/
2562/*                                                                            */
2563/*  Perform limits correlation checking; only works for early bindings        */
2564/*                                                                            */
2565/******************************************************************************/
2566void rpc_ss_ndr_unmar_check_range_correlation
2567(
2568    /* [in] */ idl_byte **p_defn_vec_ptr,
2569    /* [in] */ rpc_void_p_t array_addr,
2570    /* [in] */ rpc_void_p_t struct_addr,
2571    /* [in] */ idl_ulong_int *struct_offset_vec_ptr,
2572    /* [in] */ idl_ulong_int dimensionality,
2573    /* [in] */ IDL_bound_pair_t *bounds_list,
2574    /* [in] */ IDL_bound_pair_t *range_list,
2575    /* [in] */ IDL_msp_t IDL_msp
2576)
2577{
2578    IDL_bound_pair_t *correl_range_list;
2579    IDL_bound_pair_t normal_correl_range_list[IDL_NORMAL_DIMS];
2580    idl_boolean *early_list;
2581    idl_boolean normal_early_list[IDL_NORMAL_DIMS];
2582    idl_ulong_int i;
2583    idl_boolean add_null;
2584    idl_boolean correl_ok = idl_true;
2585
2586    if (bounds_list == NULL)
2587    {
2588#ifdef DEBUG_INTERP
2589        printf("rpc_ss_ndr_unmar_check_range_correlation: "
2590               "no bounds list provided\n");
2591#endif
2592        return;
2593    }
2594
2595    /*
2596     * If the correlated bounds are marshalled after the "NDR" bounds,
2597     * then correlation checking is only possible after unmarshalling.
2598     * This is not supported at present. To avoid attempting to read
2599     * uninitialized memory we simply return if the correlation is not
2600     * "early".
2601     *
2602     * Note: the following code assumes invariance between IDL_BOUND_
2603     * and IDL_LIMIT_. If you change these constants this will break.
2604     */
2605    if (dimensionality > IDL_NORMAL_DIMS)
2606        early_list = NULL;
2607    else
2608        early_list = normal_early_list;
2609
2610    rpc_ss_ndr_unmar_cf_early(p_defn_vec_ptr, dimensionality, FALSE,
2611                              &early_list, IDL_msp);
2612    if (early_list == NULL) {
2613        return;
2614    }
2615
2616    if (dimensionality > IDL_NORMAL_DIMS)
2617        correl_range_list = NULL;
2618    else
2619        correl_range_list = normal_correl_range_list;
2620
2621    rpc_ss_build_range_list_2(p_defn_vec_ptr, array_addr, struct_addr,
2622                              struct_offset_vec_ptr, dimensionality,
2623                              bounds_list, early_list,
2624                              &correl_range_list, &add_null, IDL_msp);
2625
2626    for (i = 0; i < dimensionality; i++)
2627    {
2628        IDL_bound_pair_t *range = &range_list[i];
2629        IDL_bound_pair_t *correl_range = &correl_range_list[i];
2630
2631        if (early_list[i] == idl_false)
2632            continue;
2633
2634        if (range->lower != correl_range->lower)
2635        {
2636#ifdef DEBUG_INTERP
2637            printf("rpc_ss_ndr_unmar_check_range_correlation: "
2638                   "lower correlation mismatch (%ld != %ld)\n",
2639                   correl_range->lower, range->lower);
2640#endif
2641            correl_ok = idl_false;
2642            break;
2643        }
2644        else if (range->upper != correl_range->upper)
2645        {
2646#ifdef DEBUG_INTERP
2647            printf("rpc_ss_ndr_unmar_check_range_correlation: "
2648                   "upper correlation mismatch (%ld != %ld)\n",
2649                   correl_range->upper, range->upper);
2650#endif
2651            correl_ok = idl_false;
2652            break;
2653        }
2654    }
2655
2656    if (dimensionality > IDL_NORMAL_DIMS)
2657    {
2658        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2659                             (byte_p_t)correl_range_list);
2660        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
2661                             (byte_p_t)early_list);
2662    }
2663
2664    if (correl_ok == idl_false)
2665        DCETHREAD_RAISE( rpc_x_invalid_bound );
2666}
2667