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**      ndrui3.c
80**
81**  FACILITY:
82**
83**      Interface Definition Language (IDL) Compiler
84**
85**  ABSTRACT:
86**
87**      NDR unmarshalling interpreter routines for - unions, pipes,
88**           [transmit_as], context handles, [v1_array]s, [v1_string]s
89**
90*/
91#if HAVE_CONFIG_H
92#include <config.h>
93#endif
94
95#include <dce/idlddefs.h>
96#include <ndrui.h>
97#include <lsysdep.h>
98#include <assert.h>
99
100/******************************************************************************/
101/*                                                                            */
102/* Unmarshall a scalar                                                        */
103/*                                                                            */
104/******************************************************************************/
105void rpc_ss_ndr_unmar_scalar
106(
107    /* [in] */  idl_byte type_byte,
108    /* [in] */  rpc_void_p_t param_addr,  /* Address item is to be marshalled
109                                                into */
110    IDL_msp_t IDL_msp
111)
112{
113    switch(type_byte)
114    {
115        case IDL_DT_BOOLEAN:
116            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
117            rpc_convert_boolean(IDL_msp->IDL_drep, ndr_g_local_drep,
118                                 IDL_msp->IDL_mp, *(idl_boolean *)param_addr);
119            IDL_msp->IDL_mp += 1;
120            IDL_msp->IDL_left_in_buff -= 1;
121            return;
122        case IDL_DT_BYTE:
123            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
124            rpc_convert_byte(IDL_msp->IDL_drep, ndr_g_local_drep,
125                                 IDL_msp->IDL_mp, *(idl_byte *)param_addr);
126            IDL_msp->IDL_mp += 1;
127            IDL_msp->IDL_left_in_buff -= 1;
128            return;
129        case IDL_DT_CHAR:
130            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
131            rpc_convert_char(IDL_msp->IDL_drep, ndr_g_local_drep,
132                                 IDL_msp->IDL_mp, *(idl_byte *)param_addr);
133            IDL_msp->IDL_mp += 1;
134            IDL_msp->IDL_left_in_buff -= 1;
135            return;
136        case IDL_DT_DOUBLE:
137            IDL_UNMAR_ALIGN_MP( IDL_msp, 8 );
138            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 8 );
139            rpc_convert_long_float(IDL_msp->IDL_drep, ndr_g_local_drep,
140                               IDL_msp->IDL_mp, *(idl_long_float *)param_addr);
141            IDL_msp->IDL_mp += 8;
142            IDL_msp->IDL_left_in_buff -= 8;
143            return;
144        case IDL_DT_ENUM:
145            IDL_UNMAR_ALIGN_MP( IDL_msp, 2 );
146            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 2 );
147            rpc_convert_enum(IDL_msp->IDL_drep, ndr_g_local_drep,
148                               IDL_msp->IDL_mp, *(int *)param_addr);
149            IDL_msp->IDL_mp += 2;
150            IDL_msp->IDL_left_in_buff -= 2;
151            return;
152        case IDL_DT_FLOAT:
153            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
154            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
155            rpc_convert_short_float(IDL_msp->IDL_drep, ndr_g_local_drep,
156                               IDL_msp->IDL_mp, *(ndr_short_float *)param_addr);
157            IDL_msp->IDL_mp += 4;
158            IDL_msp->IDL_left_in_buff -= 4;
159            return;
160        case IDL_DT_SMALL:
161            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
162            rpc_convert_small_int(IDL_msp->IDL_drep, ndr_g_local_drep,
163                               IDL_msp->IDL_mp, *(idl_small_int *)param_addr);
164            IDL_msp->IDL_mp += 1;
165            IDL_msp->IDL_left_in_buff -= 1;
166            return;
167        case IDL_DT_SHORT:
168            IDL_UNMAR_ALIGN_MP( IDL_msp, 2 );
169            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 2 );
170            rpc_convert_short_int(IDL_msp->IDL_drep, ndr_g_local_drep,
171                               IDL_msp->IDL_mp, *(idl_short_int *)param_addr);
172            IDL_msp->IDL_mp += 2;
173            IDL_msp->IDL_left_in_buff -= 2;
174            return;
175        case IDL_DT_LONG:
176            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
177            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
178            rpc_convert_long_int(IDL_msp->IDL_drep, ndr_g_local_drep,
179                                 IDL_msp->IDL_mp, *(idl_long_int *)param_addr);
180            IDL_msp->IDL_mp += 4;
181            IDL_msp->IDL_left_in_buff -= 4;
182            return;
183        case IDL_DT_HYPER:
184            IDL_UNMAR_ALIGN_MP( IDL_msp, 8 );
185            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 8 );
186            rpc_convert_hyper_int(IDL_msp->IDL_drep, ndr_g_local_drep,
187                               IDL_msp->IDL_mp, *(idl_hyper_int *)param_addr);
188            IDL_msp->IDL_mp += 8;
189            IDL_msp->IDL_left_in_buff -= 8;
190            return;
191        case IDL_DT_USMALL:
192            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
193            rpc_convert_usmall_int(IDL_msp->IDL_drep, ndr_g_local_drep,
194                               IDL_msp->IDL_mp, *(idl_usmall_int *)param_addr);
195            IDL_msp->IDL_mp += 1;
196            IDL_msp->IDL_left_in_buff -= 1;
197            return;
198        case IDL_DT_USHORT:
199            IDL_UNMAR_ALIGN_MP( IDL_msp, 2 );
200            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 2 );
201            rpc_convert_ushort_int(IDL_msp->IDL_drep, ndr_g_local_drep,
202                               IDL_msp->IDL_mp, *(idl_ushort_int *)param_addr);
203            IDL_msp->IDL_mp += 2;
204            IDL_msp->IDL_left_in_buff -= 2;
205            return;
206        case IDL_DT_ULONG:
207            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
208            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
209            rpc_convert_ulong_int(IDL_msp->IDL_drep, ndr_g_local_drep,
210                                 IDL_msp->IDL_mp, *(idl_ulong_int *)param_addr);
211            IDL_msp->IDL_mp += 4;
212            IDL_msp->IDL_left_in_buff -= 4;
213            return;
214        case IDL_DT_UHYPER:
215            IDL_UNMAR_ALIGN_MP( IDL_msp, 8 );
216            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 8 );
217            rpc_convert_uhyper_int(IDL_msp->IDL_drep, ndr_g_local_drep,
218                               IDL_msp->IDL_mp, *(idl_uhyper_int *)param_addr);
219            IDL_msp->IDL_mp += 8;
220            IDL_msp->IDL_left_in_buff -= 8;
221            return;
222        case IDL_DT_V1_ENUM:
223            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
224            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
225            rpc_convert_v1_enum(IDL_msp->IDL_drep, ndr_g_local_drep,
226                               IDL_msp->IDL_mp, *(int *)param_addr);
227            IDL_msp->IDL_mp += 4;
228            IDL_msp->IDL_left_in_buff -= 4;
229            return;
230        case IDL_DT_ERROR_STATUS:
231            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
232            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
233            rpc_convert_ulong_int( IDL_msp->IDL_drep, ndr_g_local_drep,
234                        IDL_msp->IDL_mp, *(idl_ulong_int *)(param_addr));
235#ifdef IDL_ENABLE_STATUS_MAPPING
236            rpc_ss_map_dce_to_local_status((error_status_t *)(param_addr));
237#endif
238            IDL_msp->IDL_mp += 4;
239            IDL_msp->IDL_left_in_buff -= 4;
240            return;
241        default:
242#ifdef DEBUG_INTERP
243            printf("rpc_ss_ndr_unmar_scalar: unrecognized type %d\n",
244                        type_byte);
245            exit(0);
246#endif
247            DCETHREAD_RAISE(rpc_x_coding_error);
248    }
249}
250
251/******************************************************************************/
252/*                                                                            */
253/* Unmarshall a bounded scalar                                                */
254/*                                                                            */
255/******************************************************************************/
256void rpc_ss_ndr_unmar_bounded_scalar
257(
258    /* [in] */  IDL_bound_pair_t *range_bounds,
259    /* [in] */  idl_byte type_byte,
260    /* [in] */  rpc_void_p_t param_addr,  /* Address item is to be marshalled
261                                                into */
262    IDL_msp_t IDL_msp
263)
264{
265    switch(type_byte)
266    {
267        case IDL_DT_BOOLEAN:
268            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
269            rpc_convert_boolean(IDL_msp->IDL_drep, ndr_g_local_drep,
270                                 IDL_msp->IDL_mp, *(idl_boolean *)param_addr);
271            IDL_msp->IDL_mp += 1;
272            IDL_msp->IDL_left_in_buff -= 1;
273            IDL_CHECK_RANGE_BOOLEAN( *range_bounds, param_addr );
274            return;
275        case IDL_DT_BYTE:
276            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
277            rpc_convert_byte(IDL_msp->IDL_drep, ndr_g_local_drep,
278                                 IDL_msp->IDL_mp, *(idl_byte *)param_addr);
279            IDL_msp->IDL_mp += 1;
280            IDL_msp->IDL_left_in_buff -= 1;
281            IDL_CHECK_RANGE_BYTE( *range_bounds, param_addr );
282            return;
283        case IDL_DT_CHAR:
284            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
285            rpc_convert_char(IDL_msp->IDL_drep, ndr_g_local_drep,
286                                 IDL_msp->IDL_mp, *(idl_byte *)param_addr);
287            IDL_msp->IDL_mp += 1;
288            IDL_msp->IDL_left_in_buff -= 1;
289            IDL_CHECK_RANGE_CHAR( *range_bounds, param_addr );
290            return;
291        case IDL_DT_DOUBLE:
292            IDL_UNMAR_ALIGN_MP( IDL_msp, 8 );
293            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 8 );
294            rpc_convert_long_float(IDL_msp->IDL_drep, ndr_g_local_drep,
295                               IDL_msp->IDL_mp, *(idl_long_float *)param_addr);
296            IDL_msp->IDL_mp += 8;
297            IDL_msp->IDL_left_in_buff -= 8;
298            IDL_CHECK_RANGE_DOUBLE( *range_bounds, param_addr );
299            return;
300        case IDL_DT_ENUM:
301            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 2 );
302            rpc_convert_enum(IDL_msp->IDL_drep, ndr_g_local_drep,
303                               IDL_msp->IDL_mp, *(int *)param_addr);
304            IDL_msp->IDL_mp += 2;
305            IDL_msp->IDL_left_in_buff -= 2;
306            IDL_UNMAR_ALIGN_MP( IDL_msp, 2 );
307            return;
308        case IDL_DT_FLOAT:
309            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
310            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
311            rpc_convert_short_float(IDL_msp->IDL_drep, ndr_g_local_drep,
312                               IDL_msp->IDL_mp, *(ndr_short_float *)param_addr);
313            IDL_msp->IDL_mp += 4;
314            IDL_msp->IDL_left_in_buff -= 4;
315            IDL_CHECK_RANGE_FLOAT( *range_bounds, param_addr );
316            return;
317        case IDL_DT_SMALL:
318            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
319            rpc_convert_small_int(IDL_msp->IDL_drep, ndr_g_local_drep,
320                               IDL_msp->IDL_mp, *(idl_small_int *)param_addr);
321            IDL_msp->IDL_mp += 1;
322            IDL_msp->IDL_left_in_buff -= 1;
323            IDL_CHECK_RANGE_SMALL( *range_bounds, param_addr );
324            return;
325        case IDL_DT_SHORT:
326            IDL_UNMAR_ALIGN_MP( IDL_msp, 2 );
327            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 2 );
328            rpc_convert_short_int(IDL_msp->IDL_drep, ndr_g_local_drep,
329                               IDL_msp->IDL_mp, *(idl_short_int *)param_addr);
330            IDL_msp->IDL_mp += 2;
331            IDL_msp->IDL_left_in_buff -= 2;
332            IDL_CHECK_RANGE_SHORT( *range_bounds, param_addr );
333            return;
334        case IDL_DT_LONG:
335            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
336            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
337            rpc_convert_long_int(IDL_msp->IDL_drep, ndr_g_local_drep,
338                                 IDL_msp->IDL_mp, *(idl_long_int *)param_addr);
339            IDL_msp->IDL_mp += 4;
340            IDL_msp->IDL_left_in_buff -= 4;
341            IDL_CHECK_RANGE_LONG( *range_bounds, param_addr );
342            return;
343        case IDL_DT_HYPER:
344            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 8 );
345            rpc_convert_hyper_int(IDL_msp->IDL_drep, ndr_g_local_drep,
346                               IDL_msp->IDL_mp, *(idl_hyper_int *)param_addr);
347            IDL_msp->IDL_mp += 8;
348            IDL_msp->IDL_left_in_buff -= 8;
349            IDL_UNMAR_ALIGN_MP( IDL_msp, 8 );
350            return;
351        case IDL_DT_USMALL:
352            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 1 );
353            rpc_convert_usmall_int(IDL_msp->IDL_drep, ndr_g_local_drep,
354                               IDL_msp->IDL_mp, *(idl_usmall_int *)param_addr);
355            IDL_msp->IDL_mp += 1;
356            IDL_msp->IDL_left_in_buff -= 1;
357            IDL_CHECK_RANGE_USMALL( *range_bounds, param_addr );
358            return;
359        case IDL_DT_USHORT:
360            IDL_UNMAR_ALIGN_MP( IDL_msp, 2 );
361            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 2 );
362            rpc_convert_ushort_int(IDL_msp->IDL_drep, ndr_g_local_drep,
363                               IDL_msp->IDL_mp, *(idl_ushort_int *)param_addr);
364            IDL_msp->IDL_mp += 2;
365            IDL_msp->IDL_left_in_buff -= 2;
366            IDL_CHECK_RANGE_USHORT( *range_bounds, param_addr );
367            return;
368        case IDL_DT_ULONG:
369            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
370            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
371            rpc_convert_ulong_int(IDL_msp->IDL_drep, ndr_g_local_drep,
372                                 IDL_msp->IDL_mp, *(idl_ulong_int *)param_addr);
373            IDL_msp->IDL_mp += 4;
374            IDL_msp->IDL_left_in_buff -= 4;
375            IDL_CHECK_RANGE_ULONG( *range_bounds, param_addr );
376            return;
377        case IDL_DT_UHYPER:
378            IDL_UNMAR_ALIGN_MP( IDL_msp, 8 );
379            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 8 );
380            rpc_convert_uhyper_int(IDL_msp->IDL_drep, ndr_g_local_drep,
381                               IDL_msp->IDL_mp, *(idl_uhyper_int *)param_addr);
382            IDL_msp->IDL_mp += 8;
383            IDL_msp->IDL_left_in_buff -= 8;
384            return;
385        case IDL_DT_V1_ENUM:
386            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
387            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
388            rpc_convert_v1_enum(IDL_msp->IDL_drep, ndr_g_local_drep,
389                               IDL_msp->IDL_mp, *(int *)param_addr);
390            IDL_msp->IDL_mp += 4;
391            IDL_msp->IDL_left_in_buff -= 4;
392            return;
393        case IDL_DT_ERROR_STATUS:
394            IDL_UNMAR_ALIGN_MP( IDL_msp, 4 );
395            rpc_ss_ndr_unmar_check_buffer( IDL_msp, 4 );
396            rpc_convert_ulong_int( IDL_msp->IDL_drep, ndr_g_local_drep,
397                        IDL_msp->IDL_mp, *(idl_ulong_int *)(param_addr));
398#ifdef IDL_ENABLE_STATUS_MAPPING
399            rpc_ss_map_dce_to_local_status((error_status_t *)(param_addr));
400#endif
401            IDL_msp->IDL_mp += 4;
402            IDL_msp->IDL_left_in_buff -= 4;
403            return;
404        default:
405#ifdef DEBUG_INTERP
406            printf("rpc_ss_ndr_unmar_scalar: unrecognized type %d\n",
407                        type_byte);
408            exit(0);
409#endif
410            DCETHREAD_RAISE(rpc_x_coding_error);
411    }
412}
413
414/******************************************************************************/
415/*                                                                            */
416/*  Unmarshall a union body                                                   */
417/*                                                                            */
418/******************************************************************************/
419static void rpc_ss_ndr_unmar_union_body
420(
421    /* [in] */ idl_byte *defn_vec_ptr,
422                     /* On entry GET_LONG will get number of non-default arms */
423    /* [in] */ idl_ulong_int switch_value,  /* Value of discriminant */
424    /* [in] */ rpc_void_p_t body_addr,    /* Address of the union body */
425    IDL_msp_t IDL_msp
426)
427{
428    idl_ulong_int arm_count;    /* Number of non-default arms */
429    idl_byte *arm_type_ptr;
430    idl_byte type_byte;
431    idl_ulong_int defn_index;
432    intptr_t node_number = 0;
433    IDL_bound_pair_t range_bounds;
434
435    IDL_GET_LONG_FROM_VECTOR(arm_count, defn_vec_ptr);
436    if ( ! rpc_ss_find_union_arm_defn(defn_vec_ptr, arm_count, switch_value,
437                                                                &arm_type_ptr,
438				                                IDL_msp) )
439    {
440        /* Switch not matched. Is there a default clause? */
441        defn_vec_ptr += arm_count * IDL_UNION_ARM_DESC_WIDTH;
442        if (*defn_vec_ptr == IDL_DT_DOES_NOT_EXIST)
443            DCETHREAD_RAISE( rpc_x_invalid_tag );
444        else
445            arm_type_ptr = defn_vec_ptr;
446    }
447
448    type_byte = *arm_type_ptr;
449    arm_type_ptr++;
450
451    switch(type_byte)
452    {
453        case IDL_DT_BYTE:
454        case IDL_DT_CHAR:
455        case IDL_DT_BOOLEAN:
456        case IDL_DT_DOUBLE:
457        case IDL_DT_ENUM:
458        case IDL_DT_FLOAT:
459        case IDL_DT_SMALL:
460        case IDL_DT_SHORT:
461        case IDL_DT_LONG:
462        case IDL_DT_HYPER:
463        case IDL_DT_USMALL:
464        case IDL_DT_USHORT:
465        case IDL_DT_ULONG:
466        case IDL_DT_UHYPER:
467        case IDL_DT_V1_ENUM:
468        case IDL_DT_ERROR_STATUS:
469            rpc_ss_ndr_unmar_scalar(type_byte, body_addr, IDL_msp);
470            break;
471        case IDL_DT_FIXED_STRUCT:
472            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
473                                                /* Will skip properties byte */
474            rpc_ss_ndr_unmar_struct(type_byte, IDL_msp->IDL_type_vec+defn_index,
475                                     body_addr, NULL, NULL, IDL_msp);
476            break;
477        case IDL_DT_FIXED_ARRAY:
478            IDL_DISCARD_LONG_FROM_VECTOR(arm_type_ptr);
479                                       /* Properties byte and full array defn */
480            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
481            rpc_ss_ndr_unmar_fixed_arr(defn_index, body_addr,
482                                       0, IDL_msp);
483            break;
484        case IDL_DT_ENC_UNION:
485            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
486                                                /* Will skip properties byte */
487            rpc_ss_ndr_u_enc_union_or_ptees(body_addr, defn_index, idl_false,
488                                                                      IDL_msp);
489            break;
490        case IDL_DT_FULL_PTR:
491            /* Unmarshall the node number into the space for the pointer */
492            rpc_ss_ndr_unmar_scalar(IDL_DT_ULONG, &node_number, IDL_msp);
493            *(rpc_void_p_t *)body_addr = (rpc_void_p_t)node_number;
494            break;
495        case IDL_DT_UNIQUE_PTR:
496        {
497            idl_ulong_int unique_flag;
498
499            rpc_ss_ndr_unmar_scalar(IDL_DT_ULONG, &unique_flag, IDL_msp);
500            if (unique_flag == 0)
501                *(rpc_void_p_t *)body_addr = NULL;
502            else
503                *(rpc_void_p_t *)body_addr = IDL_NEW_NODE;
504            break;
505        }
506        case IDL_DT_STRING:
507            IDL_DISCARD_LONG_FROM_VECTOR(arm_type_ptr);
508                           /* DT_VARYING, properties byte and full array defn */
509            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
510            rpc_ss_ndr_unmar_varying_arr(IDL_msp->IDL_type_vec + defn_index,
511                                         idl_false, body_addr,
512                                         0, IDL_msp);
513            break;
514        case IDL_DT_VOID:
515            break;
516        case IDL_DT_TRANSMIT_AS:
517        case IDL_DT_REPRESENT_AS:
518            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
519            rpc_ss_ndr_unmar_xmit_as(defn_index, body_addr, NULL, IDL_msp);
520            break;
521#if 0
522        case IDL_DT_INTERFACE:
523            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
524            rpc_ss_ndr_unmar_interface(defn_index, body_addr, NULL, IDL_msp);
525            break;
526#endif
527
528        case IDL_DT_V1_STRING:
529            rpc_ss_ndr_unmar_v1_string(body_addr, 0, IDL_msp);
530            break;
531        case IDL_DT_CS_ARRAY:
532            rpc_ss_ndr_unmar_cs_array(body_addr, NULL, NULL, 0, &arm_type_ptr,
533                                                                    IDL_msp);
534            break;
535        case IDL_DT_CS_TYPE:
536            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
537            rpc_ss_ndr_unmar_cs_char(body_addr, defn_index, IDL_msp);
538            break;
539        case IDL_DT_RANGE:
540            IDL_GET_RANGE_FROM_VECTOR(range_bounds, arm_type_ptr);
541            rpc_ss_ndr_unmar_bounded_scalar(&range_bounds, *arm_type_ptr,
542                                            body_addr, IDL_msp);
543            break;
544        default:
545#ifdef DEBUG_INTERP
546            printf("rpc_ss_ndr_unmar_union_body: unrecognized type %d\n",
547                        type_byte);
548            exit(0);
549#endif
550            DCETHREAD_RAISE(rpc_x_coding_error);
551    }
552}
553
554/******************************************************************************/
555/*                                                                            */
556/*  Unmarshall the pointees of a union                                        */
557/*                                                                            */
558/******************************************************************************/
559static void rpc_ss_ndr_unmar_union_ptees
560(
561    /* [in] */ idl_byte *defn_vec_ptr,
562                     /* On entry GET_LONG will get number of non-default arms */
563    /* [in] */ idl_ulong_int switch_value,  /* Value of discriminant */
564    /* [in] */ rpc_void_p_t body_addr,    /* Address of the union body */
565    IDL_msp_t IDL_msp
566)
567{
568    idl_ulong_int arm_count;    /* Number of arms */
569    idl_byte *arm_type_ptr;
570    idl_byte type_byte;
571    idl_ulong_int defn_index;
572    idl_byte *pointee_defn_ptr;
573    IDL_pointee_desc_t pointee_desc;    /* Description of pointee */
574    intptr_t node_number = 0;
575
576    IDL_GET_LONG_FROM_VECTOR(arm_count, defn_vec_ptr);
577    if ( ! rpc_ss_find_union_arm_defn(defn_vec_ptr, arm_count, switch_value,
578                                                                &arm_type_ptr,
579				                                IDL_msp) )
580    {
581        /* Switch not matched. If there were no default clause, marshalling
582            the union body would have raised an exception */
583        defn_vec_ptr += arm_count * IDL_UNION_ARM_DESC_WIDTH;
584        arm_type_ptr = defn_vec_ptr;
585    }
586
587    type_byte = *arm_type_ptr;
588    arm_type_ptr++;
589
590    switch(type_byte)
591    {
592        case IDL_DT_FIXED_STRUCT:
593            if ( ! IDL_PROP_TEST(*arm_type_ptr, IDL_PROP_HAS_PTRS) )
594                break;
595            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
596                                                /* Will skip properties byte */
597            rpc_ss_ndr_u_struct_pointees(type_byte, defn_index, body_addr, NULL,
598                                                                    IDL_msp);
599            break;
600        case IDL_DT_FIXED_ARRAY:
601            if ( ! IDL_PROP_TEST(*arm_type_ptr, IDL_PROP_HAS_PTRS) )
602                break;
603            IDL_DISCARD_LONG_FROM_VECTOR(arm_type_ptr);
604                                       /* Properties byte and full array defn */
605            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
606            rpc_ss_ndr_u_fixed_arr_ptees(defn_index, body_addr, IDL_msp);
607            break;
608        case IDL_DT_ENC_UNION:
609            if ( ! IDL_PROP_TEST(*arm_type_ptr, IDL_PROP_HAS_PTRS) )
610                break;
611            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
612                                                /* Will skip properties byte */
613            rpc_ss_ndr_u_enc_union_or_ptees(body_addr, defn_index, idl_true,
614                                                                      IDL_msp);
615            break;
616        case IDL_DT_FULL_PTR:
617            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
618                                                 /* Will skip properties byte */
619            node_number = (intptr_t)(*(rpc_void_p_t *)body_addr);
620            if (node_number != 0)
621            {
622                pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
623                pointee_desc.dimensionality = 0;
624                pointee_desc.struct_addr = NULL;
625                pointee_desc.struct_offset_vec_ptr = NULL;
626                rpc_ss_ndr_unmar_pointee_desc( type_byte,
627                                    pointee_defn_ptr, &pointee_desc,
628                                    (rpc_void_p_t *)body_addr, IDL_msp );
629                rpc_ss_ndr_unmar_pointee( type_byte,
630                                    pointee_defn_ptr, &pointee_desc,
631                                    (rpc_void_p_t *)body_addr, IDL_msp );
632                rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp );
633            }
634            break;
635	case IDL_DT_UNIQUE_PTR:
636        {
637            intptr_t unique_flag;
638
639            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
640                                                 /* Will skip properties byte */
641            unique_flag = (intptr_t)(*(rpc_void_p_t *)body_addr);
642            if (unique_flag == 0)
643            {
644                *(rpc_void_p_t *)body_addr = NULL;
645            }
646            else
647            {
648                pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
649                pointee_desc.dimensionality = 0;
650                pointee_desc.struct_addr = NULL;
651                pointee_desc.struct_offset_vec_ptr = NULL;
652                rpc_ss_ndr_unmar_pointee_desc( type_byte,
653                                    pointee_defn_ptr, &pointee_desc,
654                                    (rpc_void_p_t *)body_addr, IDL_msp );
655                if ((IDL_msp->IDL_side == IDL_server_side_k)
656                   || (*(rpc_void_p_t *)body_addr == NULL))
657                {
658                    *(rpc_void_p_t *)body_addr = IDL_NEW_NODE;
659                }
660                rpc_ss_ndr_unmar_pointee( type_byte,
661                                    pointee_defn_ptr, &pointee_desc,
662                                    (rpc_void_p_t *)body_addr, IDL_msp );
663                rpc_ss_ndr_u_rlse_pointee_desc( &pointee_desc, IDL_msp );
664            }
665            break;
666        }
667        default:
668            /* Selected arm did not contain pointers */
669            break;
670    }
671
672}
673
674/******************************************************************************/
675/*                                                                            */
676/*  Unmarshall an encapsulated union or pointees                              */
677/*                                                                            */
678/******************************************************************************/
679void rpc_ss_ndr_u_enc_union_or_ptees
680(
681    /* [in] */ rpc_void_p_t union_addr,
682    /* [in] */ idl_ulong_int defn_index,    /* Index to switch type */
683    /* [in] */ idl_boolean pointees,        /* TRUE => marshall pointees */
684    IDL_msp_t IDL_msp
685)
686{
687    idl_byte *defn_vec_ptr;
688    idl_ulong_int offset_index;
689    idl_ulong_int *offset_vec_ptr;
690    idl_byte switch_type;       /* Type of discriminant */
691    idl_ulong_int switch_value;
692    rpc_void_p_t body_addr;    /* Address of the union body */
693
694    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
695    IDL_GET_LONG_FROM_VECTOR(offset_index, defn_vec_ptr);
696    switch_type = *defn_vec_ptr;
697    defn_vec_ptr++;
698
699    if ( ! pointees )
700    {
701        /* Unmarshall discriminant */
702        rpc_ss_ndr_unmar_scalar(switch_type, union_addr, IDL_msp);
703    }
704    switch_value = (idl_ulong_int)rpc_ss_get_typed_integer(switch_type,
705                                                           union_addr, IDL_msp);
706    offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index + 1;
707                                            /* + 1 to skip over union size */
708    body_addr = (rpc_void_p_t)((idl_byte *)union_addr + *offset_vec_ptr);
709
710    if (pointees)
711    {
712        rpc_ss_ndr_unmar_union_ptees(defn_vec_ptr, switch_value, body_addr,
713                                                                      IDL_msp);
714    }
715    else
716    {
717        rpc_ss_ndr_unmar_union_body(defn_vec_ptr, switch_value, body_addr,
718                                                                      IDL_msp);
719    }
720}
721
722/******************************************************************************/
723/*                                                                            */
724/*  Unmarshall a non-encapsulated union                                       */
725/*                                                                            */
726/******************************************************************************/
727void rpc_ss_ndr_unmar_n_e_union
728(
729    /* [in] */ rpc_void_p_t union_addr,
730    /* [in] */ idl_ulong_int defn_index,    /* Points at dummy offset index
731                                                at start of union definition */
732    /* [out] */ idl_ulong_int *p_switch_value,
733    IDL_msp_t IDL_msp
734)
735{
736    idl_byte *defn_vec_ptr;
737    idl_byte switch_type;       /* Type of discriminant */
738    idl_ulong_int switch_work_area;  /* Enough storage to accomodate the
739                                biggest discriminant that can be unmarshalled */
740
741    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
742    IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Offset vec index */
743    switch_type = *defn_vec_ptr;
744    defn_vec_ptr++;
745
746    /* Unmarshall discriminant */
747    rpc_ss_ndr_unmar_scalar(switch_type, (rpc_void_p_t)&switch_work_area,
748                                                                     IDL_msp);
749    *p_switch_value = rpc_ss_get_typed_integer(switch_type,
750                                               (rpc_void_p_t)&switch_work_area,
751                                               IDL_msp);
752    /* Unmarshall union */
753    rpc_ss_ndr_unmar_union_body(defn_vec_ptr, *p_switch_value, union_addr,
754                                                                      IDL_msp);
755}
756
757/******************************************************************************/
758/*                                                                            */
759/*  Unmarshall the pointees of a non-encapsulated union                       */
760/*                                                                            */
761/******************************************************************************/
762void rpc_ss_ndr_u_n_e_union_ptees
763(
764    /* [in] */ rpc_void_p_t union_addr,
765    /* [in] */ idl_ulong_int switch_value,
766                               /* Only valid on entry if union is parameter */
767    /* [in] */ idl_ulong_int switch_index,
768                /* If union is parameter, not used */
769                /* If union is field, index in offset list for discriminant */
770    /* [in] */ idl_ulong_int defn_index,    /* Points at dummy offset index
771                                                at start of union definition */
772    /* [in] */ rpc_void_p_t struct_addr,     /* Address of structure union is
773                                        field of. NULL if union is parameter */
774    /* [in] */ idl_ulong_int *struct_offset_vec_ptr,
775                                                /* NULL if union is parameter */
776    IDL_msp_t IDL_msp
777)
778{
779    idl_byte *defn_vec_ptr;
780    idl_byte switch_type;       /* Type of discriminant */
781
782    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
783    IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Offset vec index */
784    switch_type = *defn_vec_ptr;
785    defn_vec_ptr++;
786
787    if (struct_addr != NULL)
788        rpc_ss_get_switch_from_data(switch_index, switch_type, struct_addr,
789                                 struct_offset_vec_ptr, &switch_value, IDL_msp);
790
791    rpc_ss_ndr_unmar_union_ptees(defn_vec_ptr, switch_value, union_addr,
792                                                                      IDL_msp);
793}
794
795/******************************************************************************/
796/*                                                                            */
797/*  Unmarshall a pipe chunk on the callee side                                */
798/*  As written assumes NDR transfer syntax. If we support others, this        */
799/*      routine needs to be split into a switch on transfer syntaxes and      */
800/*      an NDR specific unmarshalling routine                                 */
801/*                                                                            */
802/******************************************************************************/
803void rpc_ss_ndr_ee_unmar_pipe_chunk
804(
805    rpc_ss_pipe_state_t IDL_pipe_state,
806    rpc_void_p_t IDL_chunk_array,
807    idl_ulong_int IDL_esize,
808    idl_ulong_int *IDL_ecount_p
809)
810{
811    rpc_ss_mts_ee_pipe_state_t *p_pipe_state
812                             = (rpc_ss_mts_ee_pipe_state_t *)IDL_pipe_state;
813
814    if (p_pipe_state->pipe_drained)
815    {
816        rpc_ss_ndr_clean_up(p_pipe_state->IDL_msp);
817        DCETHREAD_RAISE(rpc_x_ss_pipe_empty);
818    }
819    if (p_pipe_state->pipe_number != *p_pipe_state->p_current_pipe)
820    {
821        rpc_ss_ndr_clean_up(p_pipe_state->IDL_msp);
822        DCETHREAD_RAISE(rpc_x_ss_pipe_order);
823    }
824
825    if (p_pipe_state->left_in_wire_array == 0)
826    {
827        /* Finished unmarshalling previous chunk sent by caller */
828        rpc_ss_ndr_unmar_scalar(IDL_DT_ULONG, &p_pipe_state->left_in_wire_array,
829                                p_pipe_state->IDL_msp);
830        if (p_pipe_state->left_in_wire_array == 0)
831        {
832            /* End of pipe */
833            p_pipe_state->pipe_drained = idl_true;
834            *p_pipe_state->p_current_pipe = p_pipe_state->next_in_pipe;
835            if (p_pipe_state->next_in_pipe < 0)
836            {
837                /* Last in pipe */
838                if (p_pipe_state->IDL_msp->IDL_elt_p->buff_dealloc
839                            && p_pipe_state->IDL_msp->IDL_elt_p->data_len != 0)
840                    (*(p_pipe_state->IDL_msp->IDL_elt_p->buff_dealloc))
841                                  (p_pipe_state->IDL_msp->IDL_elt_p->buff_addr);
842                p_pipe_state->IDL_msp->IDL_elt_p = NULL;
843            }
844            *IDL_ecount_p = 0;
845            return;
846        }
847    }
848
849    if (IDL_esize == 0)
850    {
851        /* Manager has supplied no memory for unmarshalling */
852        rpc_ss_ndr_clean_up(p_pipe_state->IDL_msp);
853        DCETHREAD_RAISE(rpc_x_ss_pipe_memory);
854    }
855
856    /* Give manager as much data as possible */
857    if (IDL_esize > p_pipe_state->left_in_wire_array)
858        *IDL_ecount_p = p_pipe_state->left_in_wire_array;
859    else
860        *IDL_ecount_p = IDL_esize;
861
862    /* Unmarshall requested data */
863    rpc_ss_ndr_u_fix_or_conf_arr( 1, IDL_ecount_p,
864                           p_pipe_state->IDL_msp->IDL_type_vec
865                                         + p_pipe_state->IDL_base_type_offset,
866                           IDL_chunk_array, 0, p_pipe_state->IDL_msp );
867
868    /* How much of the chunk supplied by the caller was not passed to the
869        manager? */
870    p_pipe_state->left_in_wire_array -= *IDL_ecount_p;
871}
872
873/******************************************************************************/
874/*                                                                            */
875/*  Unmarshall a pipe on the caller side                                      */
876/*                                                                            */
877/******************************************************************************/
878void rpc_ss_ndr_unmar_pipe
879(
880    /* [in] */ idl_ulong_int defn_index,  /* Points at pipe base type */
881    /* [in] */ rpc_void_p_t param_addr,
882    IDL_msp_t IDL_msp
883)
884{
885    idl_byte *defn_vec_ptr;
886    idl_ulong_int left_in_wire_array;
887    rpc_void_p_t chunk_ptr;
888    idl_ulong_int supplied_size;
889    idl_ulong_int element_size; /* Size of pipe base type */
890    IDL_pipe *p_pipe = (IDL_pipe *)param_addr;
891
892    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
893    element_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
894
895    left_in_wire_array = 0;
896    while (idl_true)
897    {
898        if (left_in_wire_array == 0)
899        {
900            rpc_ss_ndr_unmar_scalar(IDL_DT_ULONG, &left_in_wire_array, IDL_msp);
901            if (left_in_wire_array == 0)
902            {
903                (*p_pipe->push)(p_pipe->state, NULL, 0);
904                break;
905            }
906        }
907        (*p_pipe->alloc)(p_pipe->state, left_in_wire_array * element_size,
908                         &chunk_ptr, &supplied_size);
909        supplied_size /= element_size;
910        if (supplied_size == 0)
911            DCETHREAD_RAISE(rpc_x_ss_pipe_memory);
912        if (supplied_size > left_in_wire_array)
913            supplied_size = left_in_wire_array;
914        rpc_ss_ndr_u_fix_or_conf_arr( 1, &supplied_size, defn_vec_ptr,
915                                      chunk_ptr, 0, IDL_msp );
916        left_in_wire_array -= supplied_size;
917        (*p_pipe->push)(p_pipe->state, chunk_ptr, supplied_size);
918    }
919}
920
921/******************************************************************************/
922/*                                                                            */
923/*  Unmarshall a [transmit_as] type                                           */
924/*                                                                            */
925/******************************************************************************/
926void rpc_ss_ndr_unmar_xmit_as
927(
928    /* [in] */ idl_ulong_int defn_index,
929                          /* Points at offset index of presented type size */
930    /* [in] */ rpc_void_p_t param_addr,
931    /* [in] */ rpc_void_p_t xmit_data_buff,     /* Either NULL or the address
932                     of storage the transmitted type can be unmarshalled into */
933    IDL_msp_t IDL_msp
934)
935{
936    idl_ulong_int routine_index;    /* Index in routine vector of routine group
937                                                            for this type */
938    void (**routine_ptr)();         /* Pointer to routine group */
939    rpc_void_p_t transmitted_data;
940    idl_ulong_int transmitted_data_size; /* Storage size for transmitted data */
941    idl_byte *defn_vec_ptr;
942    idl_byte transmitted_type;      /* Type of transmitted data */
943    idl_ulong_int xmit_defn_index = 0;  /* Index of definition of constructed
944                                                            transmitted type */
945    idl_ulong_int offset_index;
946    idl_byte *struct_defn_ptr;
947    idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */
948    idl_ulong_int array_defn_index;
949    idl_byte *array_defn_ptr = NULL;
950    idl_ulong_int array_dims = 0;    /* Number of dimensions of array info */
951    idl_ulong_int *Z_values = NULL;
952    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
953    IDL_bound_pair_t *range_list;
954    IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS];
955    idl_ushort_int v1_size;
956    idl_ulong_int array_flags = 0;  /* Becomes non-zero only if transmitted
957                                       type is [v1_array] and not [v1_string] */
958    IDL_bound_pair_t range_bounds;
959    IDL_bound_pair_t *correl_bounds_list;
960    IDL_bound_pair_t normal_correl_bounds_list[IDL_NORMAL_DIMS];
961    IDL_bound_pair_t *correl_range_list;
962    IDL_bound_pair_t normal_correl_range_list[IDL_NORMAL_DIMS];
963
964    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
965    IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );  /* Presented type size ptr */
966
967    /* Get a pointer to the [transmit_as] routines for this type */
968    IDL_GET_LONG_FROM_VECTOR( routine_index, defn_vec_ptr );
969    routine_ptr = IDL_msp->IDL_rtn_vec + routine_index;
970
971    /* Get space to unmarshall the transmitted type into */
972    transmitted_type = *defn_vec_ptr;
973    if (transmitted_type == IDL_DT_STRING)
974    {
975        /* Sufficient to know whether string is varying or open array */
976        /* Note this is the only case where the [transmit_as] type can
977            be a varying or open array */
978        defn_vec_ptr++;
979        transmitted_type = *defn_vec_ptr;
980    }
981    else if (transmitted_type == IDL_DT_V1_ARRAY)
982    {
983        array_flags = IDL_M_V1_ARRAY;
984        defn_vec_ptr++;
985        transmitted_type = *defn_vec_ptr;
986    }
987    if (xmit_data_buff != NULL)
988        transmitted_data = xmit_data_buff;
989    else
990    {
991        if ( (transmitted_type == IDL_DT_CONF_STRUCT)
992            || (transmitted_type == IDL_DT_V1_CONF_STRUCT) )
993        {
994            defn_vec_ptr += 2;      /* Byte after properties byte */
995            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
996            struct_defn_ptr = IDL_msp->IDL_type_vec + xmit_defn_index;
997            IDL_GET_LONG_FROM_VECTOR(offset_index, struct_defn_ptr);
998            struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index;
999            IDL_GET_LONG_FROM_VECTOR(array_defn_index,struct_defn_ptr);
1000            array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1001            array_dims = (idl_ulong_int)*array_defn_ptr;
1002            array_defn_ptr++;
1003            /* Get Z values for correlation checking */
1004            if (array_dims > IDL_NORMAL_DIMS)
1005                Z_values = NULL;
1006            else
1007                Z_values = normal_Z_values;
1008            if (transmitted_type == IDL_DT_V1_CONF_STRUCT)
1009            {
1010                IDL_UNMAR_CUSHORT( &v1_size );
1011                assert(Z_values != NULL);
1012                *Z_values = (idl_ulong_int)v1_size;
1013            }
1014            else
1015            {
1016                rpc_ss_ndr_unmar_Z_values( array_dims, &Z_values, IDL_msp );
1017            }
1018            /* Skip over the bounds in the array defn to get to the base type */
1019            rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr,
1020                                     NULL,
1021                                     param_addr,
1022                                     struct_offset_vec_ptr,
1023                                     array_dims,
1024                                     Z_values,
1025                                     FALSE,
1026                                     NULL,
1027                                     IDL_msp );
1028
1029            if (transmitted_type == IDL_DT_V1_CONF_STRUCT)
1030            {
1031                transmitted_data_size = rpc_ss_ndr_allocation_size(
1032                                            *struct_offset_vec_ptr, 1,
1033                                            Z_values, array_defn_ptr, IDL_msp );
1034            }
1035            else
1036            {
1037                transmitted_data_size = rpc_ss_ndr_allocation_size(
1038                                            *struct_offset_vec_ptr, array_dims,
1039                                            Z_values, array_defn_ptr, IDL_msp );
1040            }
1041        }
1042        else if (transmitted_type == IDL_DT_OPEN_ARRAY)
1043        {
1044            defn_vec_ptr += 2;      /* Byte after properties byte */
1045            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
1046                                                  /* Full array definition */
1047            IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
1048            array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1049            array_dims = (idl_ulong_int)*array_defn_ptr;
1050            array_defn_ptr++;
1051            if (array_dims > IDL_NORMAL_DIMS)
1052                Z_values = NULL;
1053            else
1054                Z_values = normal_Z_values;
1055            rpc_ss_ndr_unmar_Z_values(array_dims, &Z_values, IDL_msp);
1056            if (array_dims > IDL_NORMAL_DIMS)
1057            {
1058                correl_bounds_list = NULL;
1059                correl_range_list = NULL;
1060            }
1061            else
1062            {
1063                correl_bounds_list = normal_correl_bounds_list;
1064                correl_range_list = normal_correl_range_list;
1065            }
1066#if 0
1067            rpc_ss_ndr_unmar_check_bounds_correlation( &array_defn_ptr,
1068                                     NULL,
1069                                     param_addr,
1070                                     struct_offset_vec_ptr,
1071                                     array_dims,
1072                                     Z_values,
1073                                     &correl_bounds_list,
1074                                     IDL_msp );
1075            rpc_ss_ndr_unmar_range_list( array_dims,
1076                                     array_defn_ptr[array_dims * IDL_DATA_LIMIT_PAIR_WIDTH],
1077                                     &correl_range_list, IDL_msp );
1078            rpc_ss_ndr_unmar_check_range_correlation( &array_defn_ptr,
1079                                     NULL,
1080                                     param_addr,
1081                                     struct_offset_vec_ptr,
1082                                     array_dims,
1083                                     correl_bounds_list,
1084                                     correl_range_list,
1085                                     IDL_msp );
1086#else
1087            IDL_ADV_DEFN_PTR_OVER_BOUNDS(array_defn_ptr, array_dims);
1088            array_defn_ptr += array_dims * IDL_DATA_LIMIT_PAIR_WIDTH;
1089            rpc_ss_ndr_unmar_range_list( array_dims,
1090                                     array_defn_ptr[array_dims * IDL_DATA_LIMIT_PAIR_WIDTH],
1091                                     &correl_range_list, IDL_msp );
1092#endif
1093            if (array_dims > IDL_NORMAL_DIMS)
1094            {
1095                rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)correl_bounds_list);
1096                rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)correl_range_list);
1097            }
1098            transmitted_data_size = rpc_ss_ndr_allocation_size( 0, array_dims,
1099                                            Z_values, array_defn_ptr, IDL_msp );
1100        }
1101        else
1102        {
1103            transmitted_data_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
1104        }
1105        transmitted_data = (rpc_void_p_t)rpc_ss_mem_alloc(
1106                               &IDL_msp->IDL_mem_handle, transmitted_data_size);
1107    }
1108
1109    /* Unmarshall transmitted type */
1110    switch(transmitted_type)
1111    {
1112        case IDL_DT_BOOLEAN:
1113        case IDL_DT_BYTE:
1114        case IDL_DT_CHAR:
1115        case IDL_DT_SMALL:
1116        case IDL_DT_USMALL:
1117        case IDL_DT_ENUM:
1118        case IDL_DT_SHORT:
1119        case IDL_DT_USHORT:
1120        case IDL_DT_FLOAT:
1121        case IDL_DT_LONG:
1122        case IDL_DT_ULONG:
1123        case IDL_DT_DOUBLE:
1124        case IDL_DT_HYPER:
1125        case IDL_DT_UHYPER:
1126        case IDL_DT_V1_ENUM:
1127        case IDL_DT_ERROR_STATUS:
1128            rpc_ss_ndr_unmar_scalar( transmitted_type, transmitted_data,
1129                                                                     IDL_msp );
1130            break;
1131        case IDL_DT_FIXED_STRUCT:
1132            defn_vec_ptr += 2;      /* Byte after properties byte */
1133            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
1134            rpc_ss_ndr_unmar_struct(transmitted_type,
1135                                    IDL_msp->IDL_type_vec+xmit_defn_index,
1136                                    transmitted_data, NULL, NULL, IDL_msp);
1137            break;
1138        case IDL_DT_CONF_STRUCT:
1139        case IDL_DT_V1_CONF_STRUCT:
1140            rpc_ss_ndr_unmar_struct(transmitted_type,
1141                                    IDL_msp->IDL_type_vec+xmit_defn_index,
1142                                    transmitted_data, Z_values, NULL, IDL_msp);
1143            if (array_dims > IDL_NORMAL_DIMS)
1144                rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1145                                        (byte_p_t)Z_values);
1146            break;
1147        case IDL_DT_FIXED_ARRAY:
1148            defn_vec_ptr += 2;      /* Byte after properties byte */
1149            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
1150                                             /* Discard full array definition */
1151            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
1152            rpc_ss_ndr_unmar_fixed_arr(xmit_defn_index, transmitted_data,
1153                                       0, IDL_msp);
1154            break;
1155        case IDL_DT_VARYING_ARRAY:
1156            defn_vec_ptr += 2;      /* Byte after properties byte */
1157            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
1158                                                  /* Full array definition */
1159            IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
1160            array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
1161            array_dims = (idl_ulong_int)*array_defn_ptr;
1162            array_defn_ptr++;
1163            array_defn_ptr += array_dims * (IDL_FIXED_BOUND_PAIR_WIDTH
1164                                                + IDL_DATA_LIMIT_PAIR_WIDTH);
1165            /* Now array_defn_ptr points at base type, drop through to
1166                    open array case */
1167        case IDL_DT_OPEN_ARRAY:
1168            if (array_dims > IDL_NORMAL_DIMS)
1169                range_list = NULL;
1170            else
1171                range_list = normal_range_list;
1172            assert(array_defn_ptr != NULL);
1173            rpc_ss_ndr_unmar_range_list(array_dims, *array_defn_ptr,
1174                                        &range_list, IDL_msp);
1175            rpc_ss_ndr_u_var_or_open_arr(array_dims, Z_values, array_defn_ptr,
1176                                         transmitted_data, range_list,
1177                                         array_flags, IDL_msp);
1178            if (array_dims > IDL_NORMAL_DIMS)
1179            {
1180                rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1181                                        (byte_p_t)range_list);
1182                if (transmitted_type == IDL_DT_OPEN_ARRAY)
1183                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1184                                            (byte_p_t)Z_values);
1185            }
1186            break;
1187        case IDL_DT_ENC_UNION:
1188            defn_vec_ptr += 2;      /* Byte after properties byte */
1189            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
1190            rpc_ss_ndr_u_enc_union_or_ptees(transmitted_data, xmit_defn_index,
1191                                            idl_false, IDL_msp);
1192            break;
1193        case IDL_DT_TRANSMIT_AS:
1194        case IDL_DT_REPRESENT_AS:
1195            defn_vec_ptr += 2;      /* Byte after properties byte */
1196            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
1197            rpc_ss_ndr_unmar_xmit_as(xmit_defn_index, transmitted_data, NULL,
1198                                                                     IDL_msp);
1199            break;
1200#if 0
1201        case IDL_DT_INTERFACE:
1202            defn_vec_ptr += 2;      /* Byte after properties byte */
1203            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
1204            rpc_ss_ndr_unmar_interface(xmit_defn_index, transmitted_data, NULL, IDL_msp);
1205            break;
1206#endif
1207
1208        case IDL_DT_V1_STRING:
1209            rpc_ss_ndr_unmar_v1_string(transmitted_data, 0, IDL_msp);
1210            break;
1211        case IDL_DT_RANGE:
1212            IDL_GET_RANGE_FROM_VECTOR( range_bounds, defn_vec_ptr );
1213            rpc_ss_ndr_unmar_bounded_scalar( &range_bounds, *defn_vec_ptr,
1214                                             transmitted_data, IDL_msp );
1215            break;
1216        default:
1217#ifdef DEBUG_INTERP
1218            printf("rpc_ss_ndr_unmar_xmit_as: unrecognized type %d\n",
1219                        transmitted_type);
1220            exit(0);
1221#endif
1222            DCETHREAD_RAISE(rpc_x_coding_error);
1223
1224    }
1225
1226    /* Convert to presented type */
1227    (*(routine_ptr+IDL_RTN_FROM_XMIT_INDEX))(transmitted_data, param_addr);
1228
1229    /* Release storage for transmitted type */
1230    if (xmit_data_buff == NULL)
1231        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
1232                                (byte_p_t)transmitted_data);
1233}
1234
1235/******************************************************************************/
1236/*                                                                            */
1237/*  Unmarshall a context handle                                               */
1238/*                                                                            */
1239/******************************************************************************/
1240void rpc_ss_ndr_unmar_context
1241(
1242    /* [in] */ idl_byte context_type,
1243                                    /* Need to know directionality of context */
1244    /* [in] */ rpc_void_p_t param_addr,
1245    IDL_msp_t IDL_msp
1246)
1247{
1248    ndr_context_handle wire_format;
1249    ndr_context_handle *p_wire_format;
1250    int i;
1251
1252    if (IDL_msp->IDL_side == IDL_client_side_k)
1253    {
1254        p_wire_format = &wire_format;
1255    }
1256    else
1257        p_wire_format = &((IDL_ee_context_t *)param_addr)->wire;
1258
1259    rpc_ss_ndr_unmar_scalar(IDL_DT_ULONG,
1260                         &p_wire_format->context_handle_attributes, IDL_msp);
1261    rpc_ss_ndr_unmar_scalar(IDL_DT_ULONG,
1262                         &p_wire_format->context_handle_uuid.time_low, IDL_msp);
1263    IDL_UNMAR_CUSHORT(&p_wire_format->context_handle_uuid.time_mid);
1264    IDL_UNMAR_CUSHORT(&p_wire_format->context_handle_uuid.time_hi_and_version);
1265    IDL_UNMAR_CUSMALL(&p_wire_format->context_handle_uuid.clock_seq_hi_and_reserved);
1266    IDL_UNMAR_CUSMALL(&p_wire_format->context_handle_uuid.clock_seq_low);
1267    for (i=0; i<6; i++)
1268    {
1269        rpc_ss_ndr_unmar_scalar(IDL_DT_BYTE,
1270                    &p_wire_format->context_handle_uuid.node[i], IDL_msp);
1271    }
1272
1273    /* Convert context to local form */
1274    if (IDL_msp->IDL_side == IDL_client_side_k)
1275    {
1276        rpc_ss_er_ctx_from_wire( &wire_format,
1277                                 (rpc_ss_context_t *)param_addr,
1278                                 IDL_msp->IDL_h,
1279                                 (context_type == IDL_DT_IN_OUT_CONTEXT),
1280                                 &IDL_msp->IDL_status );
1281    }
1282    else
1283    {
1284        rpc_ss_ee_ctx_from_wire( &((IDL_ee_context_t *)param_addr)->wire,
1285                                 &((IDL_ee_context_t *)param_addr)->local,
1286                                 &IDL_msp->IDL_status );
1287    }
1288}
1289
1290/******************************************************************************/
1291/*                                                                            */
1292/*  Unmarshall a varying [v1_array]                                           */
1293/*                                                                            */
1294/******************************************************************************/
1295void rpc_ss_ndr_u_v1_varying_arr
1296(
1297    /* [in] */ rpc_void_p_t array_addr,
1298    /* [in] */ idl_byte *array_defn_ptr,    /* Points at base type info */
1299    idl_ulong_int flags,
1300    IDL_msp_t IDL_msp
1301)
1302{
1303    idl_ushort_int v1_count;
1304    idl_ulong_int pseudo_Z_value;
1305    idl_byte base_type;
1306    idl_boolean unmarshall_by_copying;
1307
1308    IDL_UNMAR_CUSHORT(&v1_count);
1309    if (v1_count == 0)
1310    {
1311        if ( rpc_ss_bug_1_thru_31(IDL_BUG_1|IDL_BUG_2, IDL_msp) )
1312        {
1313            rpc_ss_ndr_arr_align_and_opt( IDL_unmarshalling_k, 1, &base_type,
1314                             array_defn_ptr, &unmarshall_by_copying, IDL_msp );
1315            if ( rpc_ss_bug_1_thru_31(IDL_BUG_1, IDL_msp)
1316                        && ( (base_type == IDL_DT_FIXED_STRUCT)
1317                                || (base_type == IDL_DT_ENC_UNION)
1318                                || (base_type == IDL_DT_TRANSMIT_AS) ) )
1319            {
1320                /* -bug 1 and non-scalar base type for [v1_array] */
1321                idl_ulong_int bug_1_align;
1322                bug_1_align = rpc_ss_ndr_bug_1_align(array_defn_ptr, IDL_msp);
1323                IDL_UNMAR_ALIGN_MP( IDL_msp, bug_1_align );
1324            }
1325        }
1326        return;
1327    }
1328    pseudo_Z_value = (idl_ulong_int)v1_count;
1329    /* Now make fixed array unmarshalling do the right thing */
1330    rpc_ss_ndr_u_fix_or_conf_arr( (*array_defn_ptr == IDL_DT_V1_STRING) ? 2 : 1,
1331                                    &pseudo_Z_value, array_defn_ptr,
1332                                    array_addr, flags, IDL_msp );
1333}
1334
1335/******************************************************************************/
1336/*                                                                            */
1337/*  Unmarshall a [v1_string]                                                  */
1338/*                                                                            */
1339/******************************************************************************/
1340void rpc_ss_ndr_unmar_v1_string
1341(
1342    /* [in] */ rpc_void_p_t param_addr,
1343    idl_ulong_int flags,
1344    IDL_msp_t IDL_msp
1345)
1346{
1347    idl_ushort_int actual_count;    /* See NDR spec */
1348    idl_byte dummy_defn_vec = IDL_DT_CHAR;  /* [v1_string] always of char */
1349    idl_ulong_int pseudo_Z_value;
1350
1351    IDL_UNMAR_CUSHORT(&actual_count);
1352    pseudo_Z_value = actual_count + 1;  /* Null terminator */
1353    rpc_ss_ndr_u_fix_or_conf_arr( 1, &pseudo_Z_value, &dummy_defn_vec,
1354                                    param_addr, flags, IDL_msp );
1355}
1356