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**      ndrmi3.c
80**
81**  FACILITY:
82**
83**      Interface Definition Language (IDL) Compiler
84**
85**  ABSTRACT:
86**
87**      NDR marshalling interpreter routines for - unions, pipes, [transmit_as],
88**          context handles, [v1_string]
89**
90*/
91#if HAVE_CONFIG_H
92#include <config.h>
93#endif
94
95#include <dce/idlddefs.h>
96#include <ndrmi.h>
97#include <lsysdep.h>
98
99/******************************************************************************/
100/*                                                                            */
101/* Marshall a scalar                                                          */
102/*                                                                            */
103/******************************************************************************/
104void rpc_ss_ndr_marsh_scalar
105(
106    /* [in] */  idl_byte type_byte,
107    /* [in] */  rpc_void_p_t param_addr,  /* Address of item to be marshalled */
108    IDL_msp_t IDL_msp
109)
110{
111    switch(type_byte)
112    {
113        case IDL_DT_BOOLEAN:
114            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
115            rpc_marshall_boolean(IDL_msp->IDL_mp, *(idl_boolean *)param_addr);
116            IDL_msp->IDL_mp += 1;
117            IDL_msp->IDL_left_in_buff -= 1;
118            return;
119        case IDL_DT_BYTE:
120            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
121            rpc_marshall_byte(IDL_msp->IDL_mp, *(idl_byte *)param_addr);
122            IDL_msp->IDL_mp += 1;
123            IDL_msp->IDL_left_in_buff -= 1;
124            return;
125        case IDL_DT_CHAR:
126            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
127            rpc_marshall_char(IDL_msp->IDL_mp, *(idl_char *)param_addr);
128            IDL_msp->IDL_mp += 1;
129            IDL_msp->IDL_left_in_buff -= 1;
130            return;
131        case IDL_DT_DOUBLE:
132            IDL_MARSH_ALIGN_MP( IDL_msp, 8 );
133            rpc_ss_ndr_marsh_check_buffer( 8, IDL_msp );
134            rpc_marshall_long_float(IDL_msp->IDL_mp,
135                                    *(idl_long_float *)param_addr);
136            IDL_msp->IDL_mp += 8;
137            IDL_msp->IDL_left_in_buff -= 8;
138            return;
139        case IDL_DT_ENUM:
140            IDL_MARSH_ALIGN_MP( IDL_msp, 2 );
141            rpc_ss_ndr_marsh_check_buffer( 2, IDL_msp );
142            rpc_marshall_enum(IDL_msp->IDL_mp, *(int *)param_addr);
143            IDL_msp->IDL_mp += 2;
144            IDL_msp->IDL_left_in_buff -= 2;
145            return;
146        case IDL_DT_FLOAT:
147            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
148            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
149            rpc_marshall_short_float(IDL_msp->IDL_mp,
150                                    *(idl_short_float *)param_addr);
151            IDL_msp->IDL_mp += 4;
152            IDL_msp->IDL_left_in_buff -= 4;
153            return;
154        case IDL_DT_SMALL:
155            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
156            rpc_marshall_small_int(IDL_msp->IDL_mp,
157                                     *(idl_small_int *)param_addr);
158            IDL_msp->IDL_mp += 1;
159            IDL_msp->IDL_left_in_buff -= 1;
160            return;
161        case IDL_DT_SHORT:
162            IDL_MARSH_ALIGN_MP( IDL_msp, 2 );
163            rpc_ss_ndr_marsh_check_buffer( 2, IDL_msp );
164            rpc_marshall_short_int(IDL_msp->IDL_mp,
165                                     *(idl_short_int *)param_addr);
166            IDL_msp->IDL_mp += 2;
167            IDL_msp->IDL_left_in_buff -= 2;
168            return;
169        case IDL_DT_LONG:
170            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
171            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
172            rpc_marshall_long_int(IDL_msp->IDL_mp, *(idl_long_int *)param_addr);
173            IDL_msp->IDL_mp += 4;
174            IDL_msp->IDL_left_in_buff -= 4;
175            return;
176        case IDL_DT_HYPER:
177            IDL_MARSH_ALIGN_MP( IDL_msp, 8 );
178            rpc_ss_ndr_marsh_check_buffer( 8, IDL_msp );
179            rpc_marshall_hyper_int(IDL_msp->IDL_mp,
180                                     *(idl_hyper_int *)param_addr);
181            IDL_msp->IDL_mp += 8;
182            IDL_msp->IDL_left_in_buff -= 8;
183            return;
184        case IDL_DT_USMALL:
185            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
186            rpc_marshall_usmall_int(IDL_msp->IDL_mp,
187                                     *(idl_usmall_int *)param_addr);
188            IDL_msp->IDL_mp += 1;
189            IDL_msp->IDL_left_in_buff -= 1;
190            return;
191        case IDL_DT_USHORT:
192            IDL_MARSH_ALIGN_MP( IDL_msp, 2 );
193            rpc_ss_ndr_marsh_check_buffer( 2, IDL_msp );
194            rpc_marshall_ushort_int(IDL_msp->IDL_mp,
195                                     *(idl_ushort_int *)param_addr);
196            IDL_msp->IDL_mp += 2;
197            IDL_msp->IDL_left_in_buff -= 2;
198            return;
199        case IDL_DT_ULONG:
200            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
201            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
202            rpc_marshall_ulong_int(IDL_msp->IDL_mp,
203                                                 *(idl_ulong_int *)param_addr);
204            IDL_msp->IDL_mp += 4;
205            IDL_msp->IDL_left_in_buff -= 4;
206            return;
207        case IDL_DT_UHYPER:
208            IDL_MARSH_ALIGN_MP( IDL_msp, 8 );
209            rpc_ss_ndr_marsh_check_buffer( 8, IDL_msp );
210            rpc_marshall_uhyper_int(IDL_msp->IDL_mp,
211                                     *(idl_uhyper_int *)param_addr);
212            IDL_msp->IDL_mp += 8;
213            IDL_msp->IDL_left_in_buff -= 8;
214            return;
215        case IDL_DT_V1_ENUM:
216            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
217            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
218            rpc_marshall_v1_enum(IDL_msp->IDL_mp, *(int *)param_addr);
219            IDL_msp->IDL_mp += 4;
220            IDL_msp->IDL_left_in_buff -= 4;
221            return;
222        case IDL_DT_ERROR_STATUS:
223            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
224            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
225            rpc_marshall_ulong_int(IDL_msp->IDL_mp,
226                                             *(idl_ulong_int *)(param_addr));
227#ifdef IDL_ENABLE_STATUS_MAPPING
228            rpc_ss_map_local_to_dce_status((error_status_t *)(IDL_msp->IDL_mp));
229#endif
230            IDL_msp->IDL_mp += 4;
231            IDL_msp->IDL_left_in_buff -= 4;
232            return;
233        default:
234#ifdef DEBUG_INTERP
235            printf("rpc_ss_ndr_marsh_scalar: unrecognized type %d\n",
236                        type_byte);
237            exit(0);
238#endif
239            DCETHREAD_RAISE(rpc_x_coding_error);
240    }
241}
242
243/******************************************************************************/
244/*                                                                            */
245/* Marshall a bounded scalar                                                  */
246/*                                                                            */
247/******************************************************************************/
248void rpc_ss_ndr_marsh_bounded_scalar
249(
250    /* [in] */  IDL_bound_pair_t *range_bounds,
251    /* [in] */  idl_byte type_byte,
252    /* [in] */  rpc_void_p_t param_addr,  /* Address of item to be marshalled */
253    IDL_msp_t IDL_msp
254)
255{
256    switch(type_byte)
257    {
258        case IDL_DT_BOOLEAN:
259            IDL_CHECK_RANGE_BOOLEAN( *range_bounds, param_addr );
260            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
261            rpc_marshall_boolean(IDL_msp->IDL_mp, *(idl_boolean *)param_addr);
262            IDL_msp->IDL_mp += 1;
263            IDL_msp->IDL_left_in_buff -= 1;
264            return;
265        case IDL_DT_BYTE:
266            IDL_CHECK_RANGE_BYTE( *range_bounds, param_addr );
267            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
268            rpc_marshall_byte(IDL_msp->IDL_mp, *(idl_byte *)param_addr);
269            IDL_msp->IDL_mp += 1;
270            IDL_msp->IDL_left_in_buff -= 1;
271            return;
272        case IDL_DT_CHAR:
273            IDL_CHECK_RANGE_CHAR( *range_bounds, param_addr );
274            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
275            rpc_marshall_char(IDL_msp->IDL_mp, *(idl_char *)param_addr);
276            IDL_msp->IDL_mp += 1;
277            IDL_msp->IDL_left_in_buff -= 1;
278            return;
279        case IDL_DT_DOUBLE:
280            IDL_CHECK_RANGE_DOUBLE( *range_bounds, param_addr );
281            IDL_MARSH_ALIGN_MP( IDL_msp, 8 );
282            rpc_ss_ndr_marsh_check_buffer( 8, IDL_msp );
283            rpc_marshall_long_float(IDL_msp->IDL_mp,
284                                    *(idl_long_float *)param_addr);
285            IDL_msp->IDL_mp += 8;
286            IDL_msp->IDL_left_in_buff -= 8;
287            return;
288        case IDL_DT_ENUM:
289            IDL_MARSH_ALIGN_MP( IDL_msp, 2 );
290            rpc_ss_ndr_marsh_check_buffer( 2, IDL_msp );
291            rpc_marshall_enum(IDL_msp->IDL_mp, *(int *)param_addr);
292            IDL_msp->IDL_mp += 2;
293            IDL_msp->IDL_left_in_buff -= 2;
294            return;
295        case IDL_DT_FLOAT:
296            IDL_CHECK_RANGE_FLOAT( *range_bounds, param_addr );
297            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
298            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
299            rpc_marshall_short_float(IDL_msp->IDL_mp,
300                                    *(idl_short_float *)param_addr);
301            IDL_msp->IDL_mp += 4;
302            IDL_msp->IDL_left_in_buff -= 4;
303            return;
304        case IDL_DT_SMALL:
305            IDL_CHECK_RANGE_SMALL( *range_bounds, param_addr );
306            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
307            rpc_marshall_small_int(IDL_msp->IDL_mp,
308                                     *(idl_small_int *)param_addr);
309            IDL_msp->IDL_mp += 1;
310            IDL_msp->IDL_left_in_buff -= 1;
311            return;
312        case IDL_DT_SHORT:
313            IDL_CHECK_RANGE_SHORT( *range_bounds, param_addr );
314            IDL_MARSH_ALIGN_MP( IDL_msp, 2 );
315            rpc_ss_ndr_marsh_check_buffer( 2, IDL_msp );
316            rpc_marshall_short_int(IDL_msp->IDL_mp,
317                                     *(idl_short_int *)param_addr);
318            IDL_msp->IDL_mp += 2;
319            IDL_msp->IDL_left_in_buff -= 2;
320            return;
321        case IDL_DT_LONG:
322            IDL_CHECK_RANGE_LONG( *range_bounds, param_addr );
323            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
324            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
325            rpc_marshall_long_int(IDL_msp->IDL_mp, *(idl_long_int *)param_addr);
326            IDL_msp->IDL_mp += 4;
327            IDL_msp->IDL_left_in_buff -= 4;
328            return;
329        case IDL_DT_HYPER:
330            IDL_MARSH_ALIGN_MP( IDL_msp, 8 );
331            rpc_ss_ndr_marsh_check_buffer( 8, IDL_msp );
332            rpc_marshall_hyper_int(IDL_msp->IDL_mp,
333                                     *(idl_hyper_int *)param_addr);
334            IDL_msp->IDL_mp += 8;
335            IDL_msp->IDL_left_in_buff -= 8;
336            return;
337        case IDL_DT_USMALL:
338            IDL_CHECK_RANGE_USMALL( *range_bounds, param_addr );
339            rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp );
340            rpc_marshall_usmall_int(IDL_msp->IDL_mp,
341                                     *(idl_usmall_int *)param_addr);
342            IDL_msp->IDL_mp += 1;
343            IDL_msp->IDL_left_in_buff -= 1;
344            return;
345        case IDL_DT_USHORT:
346            IDL_CHECK_RANGE_USHORT( *range_bounds, param_addr );
347            IDL_MARSH_ALIGN_MP( IDL_msp, 2 );
348            rpc_ss_ndr_marsh_check_buffer( 2, IDL_msp );
349            rpc_marshall_ushort_int(IDL_msp->IDL_mp,
350                                     *(idl_ushort_int *)param_addr);
351            IDL_msp->IDL_mp += 2;
352            IDL_msp->IDL_left_in_buff -= 2;
353            return;
354        case IDL_DT_ULONG:
355            IDL_CHECK_RANGE_ULONG( *range_bounds, param_addr );
356            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
357            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
358            rpc_marshall_ulong_int(IDL_msp->IDL_mp,
359                                                 *(idl_ulong_int *)param_addr);
360            IDL_msp->IDL_mp += 4;
361            IDL_msp->IDL_left_in_buff -= 4;
362            return;
363        case IDL_DT_UHYPER:
364            IDL_MARSH_ALIGN_MP( IDL_msp, 8 );
365            rpc_ss_ndr_marsh_check_buffer( 8, IDL_msp );
366            rpc_marshall_uhyper_int(IDL_msp->IDL_mp,
367                                     *(idl_uhyper_int *)param_addr);
368            IDL_msp->IDL_mp += 8;
369            IDL_msp->IDL_left_in_buff -= 8;
370            return;
371        case IDL_DT_V1_ENUM:
372            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
373            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
374            rpc_marshall_v1_enum(IDL_msp->IDL_mp, *(int *)param_addr);
375            IDL_msp->IDL_mp += 4;
376            IDL_msp->IDL_left_in_buff -= 4;
377            return;
378        case IDL_DT_ERROR_STATUS:
379            IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
380            rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
381            rpc_marshall_ulong_int(IDL_msp->IDL_mp,
382                                             *(idl_ulong_int *)(param_addr));
383#ifdef IDL_ENABLE_STATUS_MAPPING
384            rpc_ss_map_local_to_dce_status((error_status_t *)(IDL_msp->IDL_mp));
385#endif
386            IDL_msp->IDL_mp += 4;
387            IDL_msp->IDL_left_in_buff -= 4;
388            return;
389        default:
390#ifdef DEBUG_INTERP
391            printf("rpc_ss_ndr_marsh_bounded_scalar: unrecognized type %d\n",
392                        type_byte);
393            exit(0);
394#endif
395            DCETHREAD_RAISE(rpc_x_coding_error);
396    }
397}
398
399/******************************************************************************/
400/*                                                                            */
401/*  Marshall a union body                                                     */
402/*                                                                            */
403/******************************************************************************/
404static void rpc_ss_ndr_marsh_union_body
405(
406    /* [in] */ idl_byte *defn_vec_ptr,
407                     /* On entry GET_LONG will get number of non-default arms */
408    /* [in] */ idl_ulong_int switch_value,  /* Value of discriminant */
409    /* [in] */ rpc_void_p_t body_addr,    /* Address of the union body */
410    IDL_msp_t IDL_msp
411)
412{
413    idl_ulong_int arm_count;    /* Number of non-default arms */
414    idl_byte *arm_type_ptr;
415    idl_byte type_byte;
416    idl_ulong_int defn_index;
417    idl_ulong_int node_number;
418    long already_marshalled;
419    IDL_bound_pair_t range_bounds;
420
421    IDL_GET_LONG_FROM_VECTOR(arm_count, defn_vec_ptr);
422    if ( ! rpc_ss_find_union_arm_defn(defn_vec_ptr, arm_count, switch_value,
423                                                                &arm_type_ptr,
424				                                IDL_msp) )
425    {
426        /* Switch not matched. Is there a default clause? */
427        defn_vec_ptr += arm_count * IDL_UNION_ARM_DESC_WIDTH;
428        if (*defn_vec_ptr == IDL_DT_DOES_NOT_EXIST)
429            DCETHREAD_RAISE( rpc_x_invalid_tag );
430        else
431            arm_type_ptr = defn_vec_ptr;
432    }
433
434    type_byte = *arm_type_ptr;
435    arm_type_ptr++;
436
437    switch(type_byte)
438    {
439        case IDL_DT_BYTE:
440        case IDL_DT_CHAR:
441        case IDL_DT_BOOLEAN:
442        case IDL_DT_DOUBLE:
443        case IDL_DT_ENUM:
444        case IDL_DT_FLOAT:
445        case IDL_DT_SMALL:
446        case IDL_DT_SHORT:
447        case IDL_DT_LONG:
448        case IDL_DT_HYPER:
449        case IDL_DT_USMALL:
450        case IDL_DT_USHORT:
451        case IDL_DT_ULONG:
452        case IDL_DT_UHYPER:
453        case IDL_DT_V1_ENUM:
454        case IDL_DT_ERROR_STATUS:
455            rpc_ss_ndr_marsh_scalar(type_byte, body_addr, IDL_msp);
456            break;
457        case IDL_DT_FIXED_STRUCT:
458            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
459                                                /* Will skip properties byte */
460            rpc_ss_ndr_marsh_struct(type_byte, defn_index, body_addr, IDL_msp);
461            break;
462        case IDL_DT_FIXED_ARRAY:
463            IDL_DISCARD_LONG_FROM_VECTOR(arm_type_ptr);
464                                       /* Properties byte and full array defn */
465            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
466            rpc_ss_ndr_marsh_fixed_arr(defn_index, body_addr, 0, IDL_msp);
467            break;
468        case IDL_DT_ENC_UNION:
469            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
470                                                /* Will skip properties byte */
471            rpc_ss_ndr_m_enc_union_or_ptees(body_addr, defn_index, idl_false,
472                                                                      IDL_msp);
473            break;
474        case IDL_DT_FULL_PTR:
475            node_number = rpc_ss_register_node( IDL_msp->IDL_node_table,
476                                                *(byte_p_t *)body_addr,
477                                               ndr_false, &already_marshalled );
478            IDL_MARSH_ULONG( &node_number );
479            break;
480        case IDL_DT_UNIQUE_PTR:
481            node_number = ((byte_p_t)*(rpc_void_p_t *)body_addr != NULL);
482            IDL_MARSH_ULONG( &node_number );
483            break;
484        case IDL_DT_STRING:
485            IDL_DISCARD_LONG_FROM_VECTOR(arm_type_ptr);
486                           /* DT_VARYING, properties byte and full array defn */
487            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
488            rpc_ss_ndr_marsh_varying_arr(defn_index, body_addr, NULL, NULL, 0,
489                                         IDL_msp);
490            break;
491        case IDL_DT_VOID:
492            break;
493        case IDL_DT_TRANSMIT_AS:
494        case IDL_DT_REPRESENT_AS:
495            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
496            rpc_ss_ndr_marsh_xmit_as(defn_index, body_addr, IDL_msp);
497            break;
498#if 0
499        case IDL_DT_INTERFACE:
500            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
501            rpc_ss_ndr_marsh_interface(defn_index, body_addr, IDL_msp);
502            break;
503#endif
504
505        case IDL_DT_V1_STRING:
506            IDL_DISCARD_LONG_FROM_VECTOR(arm_type_ptr);
507                           /* DT_VARYING, properties byte and full array defn */
508            IDL_DISCARD_LONG_FROM_VECTOR(arm_type_ptr);
509                                                      /* Flattened array defn */
510            rpc_ss_ndr_marsh_v1_string(body_addr, 0, IDL_msp);
511            break;
512        case IDL_DT_CS_TYPE:
513            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
514            rpc_ss_ndr_marsh_cs_char(body_addr, defn_index, IDL_msp);
515            break;
516        case IDL_DT_CS_ARRAY:
517            rpc_ss_ndr_m_fixed_cs_array(body_addr, &arm_type_ptr, IDL_msp);
518            break;
519        case IDL_DT_RANGE:
520            IDL_GET_RANGE_FROM_VECTOR(range_bounds, arm_type_ptr);
521            rpc_ss_ndr_marsh_bounded_scalar(&range_bounds, *arm_type_ptr,
522                                            body_addr, IDL_msp);
523            break;
524        default:
525#ifdef DEBUG_INTERP
526            printf("rpc_ss_ndr_marsh_union_body: unrecognized type %d\n",
527                        type_byte);
528            exit(0);
529#endif
530            DCETHREAD_RAISE(rpc_x_coding_error);
531    }
532}
533
534/******************************************************************************/
535/*                                                                            */
536/*  Marshall the pointees of a union                                          */
537/*                                                                            */
538/******************************************************************************/
539static void rpc_ss_ndr_marsh_union_ptees
540(
541    /* [in] */ idl_byte *defn_vec_ptr,
542                     /* On entry GET_LONG will get number of non-default arms */
543    /* [in] */ idl_ulong_int switch_value,  /* Value of discriminant */
544    /* [in] */ rpc_void_p_t body_addr,    /* Address of the union body */
545    IDL_msp_t IDL_msp
546)
547{
548    idl_ulong_int arm_count;    /* Number of arms */
549    idl_byte *arm_type_ptr;
550    idl_byte type_byte;
551    idl_ulong_int defn_index;
552    idl_byte *pointee_defn_ptr;
553    IDL_pointee_desc_t pointee_desc;    /* Description of pointee */
554
555    IDL_GET_LONG_FROM_VECTOR(arm_count, defn_vec_ptr);
556    if ( ! rpc_ss_find_union_arm_defn(defn_vec_ptr, arm_count, switch_value,
557                                                                &arm_type_ptr,
558				                                IDL_msp) )
559    {
560        /* Switch not matched. If there were no default clause, marshalling
561            the union body would have raised an exception */
562        defn_vec_ptr += arm_count * IDL_UNION_ARM_DESC_WIDTH;
563        arm_type_ptr = defn_vec_ptr;
564    }
565
566    type_byte = *arm_type_ptr;
567    arm_type_ptr++;
568
569    switch(type_byte)
570    {
571        case IDL_DT_FIXED_STRUCT:
572            if ( ! IDL_PROP_TEST(*arm_type_ptr, IDL_PROP_HAS_PTRS) )
573                break;
574            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
575                                                /* Will skip properties byte */
576            rpc_ss_ndr_m_struct_pointees(type_byte, defn_index, body_addr,
577                                                                    IDL_msp);
578            break;
579        case IDL_DT_FIXED_ARRAY:
580            if ( ! IDL_PROP_TEST(*arm_type_ptr, IDL_PROP_HAS_PTRS) )
581                break;
582            IDL_DISCARD_LONG_FROM_VECTOR(arm_type_ptr);
583                                       /* Properties byte and full array defn */
584            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
585            rpc_ss_ndr_m_dfc_arr_ptees(defn_index, body_addr, NULL, NULL, 0,
586                                                                     IDL_msp);
587            break;
588        case IDL_DT_ENC_UNION:
589            if ( ! IDL_PROP_TEST(*arm_type_ptr, IDL_PROP_HAS_PTRS) )
590                break;
591            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
592                                                /* Will skip properties byte */
593            rpc_ss_ndr_m_enc_union_or_ptees(body_addr, defn_index, idl_true,
594                                                                      IDL_msp);
595            break;
596        case IDL_DT_FULL_PTR:
597            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
598                                                 /* Will skip properties byte */
599            pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
600            if (*(rpc_void_p_t *)body_addr != NULL)
601            {
602                pointee_desc.dimensionality = 0;
603                rpc_ss_pointee_desc_from_data( pointee_defn_ptr,
604                                        *(rpc_void_p_t *)body_addr,
605                                        NULL, NULL, &pointee_desc, IDL_msp );
606                rpc_ss_ndr_marsh_pointee( pointee_defn_ptr,
607                                        *(rpc_void_p_t *)body_addr,
608                                        idl_true, &pointee_desc, IDL_msp );
609                rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
610            }
611            break;
612        case IDL_DT_UNIQUE_PTR:
613            IDL_GET_LONG_FROM_VECTOR(defn_index, arm_type_ptr);
614                                                 /* Will skip properties byte */
615            pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
616            if (*(rpc_void_p_t *)body_addr != NULL)
617            {
618                pointee_desc.dimensionality = 0;
619                rpc_ss_pointee_desc_from_data( pointee_defn_ptr,
620                                        *(rpc_void_p_t *)body_addr,
621                                        NULL, NULL, &pointee_desc, IDL_msp );
622                rpc_ss_ndr_marsh_pointee( pointee_defn_ptr,
623                                        *(rpc_void_p_t *)body_addr,
624                                        idl_false, &pointee_desc, IDL_msp );
625                rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
626            }
627            break;
628        default:
629            /* Selected arm did not contain pointers */
630            break;
631    }
632
633}
634
635/******************************************************************************/
636/*                                                                            */
637/*  Marshall an encapsulated union or pointees                                */
638/*                                                                            */
639/******************************************************************************/
640void rpc_ss_ndr_m_enc_union_or_ptees
641(
642    /* [in] */ rpc_void_p_t union_addr,
643    /* [in] */ idl_ulong_int defn_index,    /* Index to switch type */
644    /* [in] */ idl_boolean pointees,        /* TRUE => marshall pointees */
645    IDL_msp_t IDL_msp
646)
647{
648    idl_byte *defn_vec_ptr;
649    idl_ulong_int offset_index;
650    idl_ulong_int *offset_vec_ptr;
651    idl_byte switch_type;       /* Type of discriminant */
652    idl_ulong_int switch_value;
653    rpc_void_p_t body_addr;    /* Address of the union body */
654
655    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
656    IDL_GET_LONG_FROM_VECTOR(offset_index, defn_vec_ptr);
657    switch_type = *defn_vec_ptr;
658    defn_vec_ptr++;
659
660    switch_value = (idl_ulong_int)rpc_ss_get_typed_integer(switch_type,
661                                                           union_addr, IDL_msp);
662    offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index + 1;
663                                            /* + 1 to skip over union size */
664    body_addr = (rpc_void_p_t)((idl_byte *)union_addr + *offset_vec_ptr);
665
666    if (pointees)
667    {
668        rpc_ss_ndr_marsh_union_ptees(defn_vec_ptr, switch_value, body_addr,
669                                                                      IDL_msp);
670    }
671    else
672    {
673        /* Marshall discriminant */
674        rpc_ss_ndr_marsh_scalar(switch_type, union_addr, IDL_msp);
675        /* Marshall arm */
676        rpc_ss_ndr_marsh_union_body(defn_vec_ptr, switch_value, body_addr,
677                                                                      IDL_msp);
678    }
679}
680
681/******************************************************************************/
682/*                                                                            */
683/*  Marshall a non-encapsulated union or pointees                             */
684/*                                                                            */
685/******************************************************************************/
686void rpc_ss_ndr_m_n_e_union_or_ptees
687(
688    /* [in] */ rpc_void_p_t union_addr,
689    /* [in] */ idl_ulong_int switch_index,
690                /* If union is parameter, index in param list of discriminant */
691                /* If union is field, index in offset list for discriminant */
692    /* [in] */ idl_ulong_int defn_index,    /* Points at dummy offset index
693                                                at start of union definition */
694    /* [in] */ rpc_void_p_t struct_addr,     /* Address of structure union is
695                                        field of. NULL if union is parameter */
696    /* [in] */ idl_ulong_int *struct_offset_vec_ptr,
697                                                /* NULL if union is parameter */
698    /* [in] */ idl_boolean pointees,        /* TRUE => marshall pointees */
699    IDL_msp_t IDL_msp
700)
701{
702    idl_byte *defn_vec_ptr;
703    idl_byte switch_type;       /* Type of discriminant */
704    idl_ulong_int switch_value;
705    rpc_void_p_t switch_addr;    /* Address of the discriminant */
706
707    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
708    IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr ); /* Offset vec index */
709    switch_type = *defn_vec_ptr;
710    defn_vec_ptr++;
711
712    rpc_ss_get_switch_from_data(switch_index, switch_type, struct_addr,
713                                 struct_offset_vec_ptr, &switch_value, IDL_msp);
714
715    if (pointees)
716    {
717        rpc_ss_ndr_marsh_union_ptees(defn_vec_ptr, switch_value, union_addr,
718                                                                      IDL_msp);
719    }
720    else
721    {
722        /* Marshall discriminant */
723        if ( struct_addr == NULL )
724            switch_addr = IDL_msp->IDL_param_vec[switch_index];
725        else
726            switch_addr = (rpc_void_p_t)((idl_byte *)struct_addr
727                                       + struct_offset_vec_ptr[switch_index]);
728        rpc_ss_ndr_marsh_scalar(switch_type, switch_addr, IDL_msp);
729        /* Marshall arm */
730        rpc_ss_ndr_marsh_union_body(defn_vec_ptr, switch_value, union_addr,
731                                                                      IDL_msp);
732    }
733}
734
735/******************************************************************************/
736/*                                                                            */
737/*  Marshall a pipe chunk on the callee side                                  */
738/*  As written assumes NDR transfer syntax. If we support others, this        */
739/*      routine needs to be split into a switch on transfer syntaxes and      */
740/*      an NDR specific marshalling routine                                   */
741/*                                                                            */
742/******************************************************************************/
743void rpc_ss_ndr_ee_marsh_pipe_chunk
744(
745    rpc_ss_pipe_state_t IDL_pipe_state,
746    rpc_void_p_t IDL_chunk_array,
747    idl_ulong_int IDL_pipe_chunk_size
748)
749{
750    IDL_bound_pair_t chunk_bounds;
751    rpc_ss_mts_ee_pipe_state_t *p_pipe_state
752                             = (rpc_ss_mts_ee_pipe_state_t *)IDL_pipe_state;
753
754    p_pipe_state->IDL_msp->IDL_marsh_pipe = idl_true;
755
756    if (p_pipe_state->pipe_filled)
757    {
758        rpc_ss_ndr_clean_up(p_pipe_state->IDL_msp);
759        DCETHREAD_RAISE(rpc_x_ss_pipe_closed);
760    }
761    if (p_pipe_state->pipe_number != -*p_pipe_state->p_current_pipe)
762    {
763        rpc_ss_ndr_clean_up(p_pipe_state->IDL_msp);
764        DCETHREAD_RAISE(rpc_x_ss_pipe_order);
765    }
766
767    /* Marshall the chunk */
768    rpc_ss_ndr_marsh_scalar( IDL_DT_ULONG, &IDL_pipe_chunk_size,
769                             p_pipe_state->IDL_msp );   /* Z-value */
770    if (IDL_pipe_chunk_size == 0)
771    {
772        /* End of pipe */
773        p_pipe_state->pipe_filled = idl_true;
774        *p_pipe_state->p_current_pipe = p_pipe_state->next_out_pipe;
775    }
776    else
777    {
778        /* Marshall chunk data */
779        chunk_bounds.lower = 1;
780        chunk_bounds.upper = IDL_pipe_chunk_size;
781        rpc_ss_ndr_m_fix_or_conf_arr( IDL_chunk_array, 1, &chunk_bounds,
782                                      p_pipe_state->IDL_msp->IDL_type_vec
783                                          + p_pipe_state->IDL_base_type_offset,
784                                      IDL_M_CONF_ARRAY, p_pipe_state->IDL_msp );
785    }
786    /* [out] pipes precede other [out]s. IDL_marsh_pipe will be reset when the
787        interpreter is called to marshall the other [out]s */
788}
789
790/******************************************************************************/
791/*                                                                            */
792/*  Marshall a pipe on the caller side                                        */
793/*                                                                            */
794/******************************************************************************/
795void rpc_ss_ndr_marsh_pipe
796(
797    /* [in] */ idl_ulong_int defn_index,  /* Points at pipe base type */
798    /* [in] */ rpc_void_p_t param_addr,
799    IDL_msp_t IDL_msp
800)
801{
802    idl_byte *defn_vec_ptr;
803    idl_ulong_int element_size; /* Size of pipe base type */
804    rpc_void_p_t chunk_ptr;     /* Pointer to pipe chunk */
805    idl_ulong_int buff_size;    /* Size of user buffer in bytes */
806    idl_ulong_int chunk_size;   /* Number of elements in chunk */
807    IDL_bound_pair_t bounds_list;
808    IDL_pipe *p_pipe = (IDL_pipe *)param_addr;
809
810    IDL_msp->IDL_marsh_pipe = idl_true;
811    IDL_msp->IDL_restartable = idl_false;
812
813    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
814    element_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
815
816    do {
817        (*p_pipe->alloc)(p_pipe->state,
818                    (element_size > NIDL_PIPE_BUFF_SIZE/IDL_MIN_PIPE_CHUNK_SIZE)
819                                ? IDL_MIN_PIPE_CHUNK_SIZE * element_size
820                                : NIDL_PIPE_BUFF_SIZE,
821                         &chunk_ptr,
822                         &buff_size);
823        if (element_size > buff_size)
824            DCETHREAD_RAISE(rpc_x_ss_pipe_memory);
825        (*p_pipe->pull)(p_pipe->state, chunk_ptr, buff_size/element_size,
826                        &chunk_size);
827        rpc_ss_ndr_marsh_scalar(IDL_DT_ULONG, &chunk_size, IDL_msp);
828        if (chunk_size != 0)
829        {
830            bounds_list.lower = 1;
831            bounds_list.upper = chunk_size;
832            rpc_ss_ndr_m_fix_or_conf_arr( chunk_ptr, 1, &bounds_list,
833                                      defn_vec_ptr, IDL_M_CONF_ARRAY, IDL_msp );
834        }
835    } while (chunk_size != 0);
836
837    /* As pipes are the last [in] parameters, no need to reset IDL_marsh_pipe */
838}
839
840/******************************************************************************/
841/*                                                                            */
842/*  Marshall a [transmit_as] type                                             */
843/*                                                                            */
844/******************************************************************************/
845void rpc_ss_ndr_marsh_xmit_as
846(
847    /* [in] */ idl_ulong_int defn_index,
848                          /* Points at offset index of presented type size */
849    /* [in] */ rpc_void_p_t param_addr,
850    IDL_msp_t IDL_msp
851)
852{
853    idl_ulong_int routine_index;    /* Index in routine vector of routine group
854                                                            for this type */
855    void (**routine_ptr)();         /* Pointer to routine group */
856    rpc_void_p_t transmitted_data;
857    idl_byte *defn_vec_ptr;
858    idl_byte transmitted_type;      /* Type of transmitted data */
859    idl_ulong_int xmit_defn_index;  /* Index of definition of constructed
860                                                            transmitted type */
861    idl_ulong_int array_flags = 0;  /* Becomes non-zero only if transmitted
862                                       type is [v1_array] and not [v1_string] */
863    IDL_bound_pair_t range_bounds;
864
865    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
866    IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );  /* Presented type size ptr */
867
868    /* Get a pointer to the [transmit_as] routines for this type */
869    IDL_GET_LONG_FROM_VECTOR( routine_index, defn_vec_ptr );
870    routine_ptr = IDL_msp->IDL_rtn_vec + routine_index;
871
872    /* Convert presented type to transmitted type */
873    (*(routine_ptr+IDL_RTN_TO_XMIT_INDEX))(param_addr, &transmitted_data);
874    (IDL_msp->IDL_m_xmit_level)++;
875
876    /* Marshall transmitted type */
877    transmitted_type = *defn_vec_ptr;
878    if (transmitted_type == IDL_DT_STRING)
879    {
880        /* Sufficient to know whether string is varying or open array */
881        /* Note this is the only case where the [transmit_as] type can
882            be a varying or open array */
883        defn_vec_ptr++;
884        transmitted_type = *defn_vec_ptr;
885    }
886    else if (transmitted_type == IDL_DT_V1_ARRAY)
887    {
888        array_flags = IDL_M_V1_ARRAY;
889        defn_vec_ptr++;
890        transmitted_type = *defn_vec_ptr;
891    }
892    switch(transmitted_type)
893    {
894        case IDL_DT_BOOLEAN:
895        case IDL_DT_BYTE:
896        case IDL_DT_CHAR:
897        case IDL_DT_SMALL:
898        case IDL_DT_USMALL:
899        case IDL_DT_ENUM:
900        case IDL_DT_SHORT:
901        case IDL_DT_USHORT:
902        case IDL_DT_FLOAT:
903        case IDL_DT_LONG:
904        case IDL_DT_ULONG:
905        case IDL_DT_DOUBLE:
906        case IDL_DT_HYPER:
907        case IDL_DT_UHYPER:
908        case IDL_DT_V1_ENUM:
909        case IDL_DT_ERROR_STATUS:
910            rpc_ss_ndr_marsh_scalar( transmitted_type, transmitted_data,
911                                                                     IDL_msp );
912            break;
913        case IDL_DT_CONF_STRUCT:
914        case IDL_DT_V1_CONF_STRUCT:
915        case IDL_DT_FIXED_STRUCT:
916            defn_vec_ptr += 2;      /* Byte after properties byte */
917            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index,defn_vec_ptr);
918            rpc_ss_ndr_marsh_struct(transmitted_type, xmit_defn_index,
919                                    transmitted_data, IDL_msp);
920            break;
921        case IDL_DT_FIXED_ARRAY:
922            defn_vec_ptr += 2;      /* Byte after properties byte */
923            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
924                                             /* Discard full array definition */
925            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index,defn_vec_ptr);
926            rpc_ss_ndr_marsh_fixed_arr(xmit_defn_index,
927                                       transmitted_data, 0, IDL_msp);
928            break;
929        case IDL_DT_VARYING_ARRAY:
930            defn_vec_ptr += 2;      /* Byte after properties byte */
931            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
932                                                    /* Full array definition */
933            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
934            rpc_ss_ndr_marsh_varying_arr(xmit_defn_index, transmitted_data,
935                                     NULL, NULL, array_flags, IDL_msp);
936            break;
937        case IDL_DT_OPEN_ARRAY:
938            defn_vec_ptr += 2;      /* Byte after properties byte */
939            IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
940                                                    /* Full array definition */
941            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
942            rpc_ss_ndr_marsh_open_arr(xmit_defn_index, transmitted_data,
943                                      array_flags, IDL_msp);
944            break;
945        case IDL_DT_ENC_UNION:
946            defn_vec_ptr += 2;      /* Byte after properties byte */
947            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
948            rpc_ss_ndr_m_enc_union_or_ptees(transmitted_data, xmit_defn_index,
949                                            idl_false, IDL_msp);
950            break;
951        case IDL_DT_TRANSMIT_AS:
952        case IDL_DT_REPRESENT_AS:
953            defn_vec_ptr += 2;      /* Byte after properties byte */
954            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
955            rpc_ss_ndr_marsh_xmit_as(xmit_defn_index, transmitted_data,
956                                                                     IDL_msp);
957            break;
958#if 0
959        case IDL_DT_INTERFACE:
960            defn_vec_ptr += 2;      /* Byte after properties byte */
961            IDL_GET_LONG_FROM_VECTOR(xmit_defn_index, defn_vec_ptr);
962            rpc_ss_ndr_marsh_interface(xmit_defn_index, transmitted_data, IDL_msp);
963            break;
964#endif
965
966        case IDL_DT_V1_STRING:
967            rpc_ss_ndr_marsh_v1_string(transmitted_data, 0, IDL_msp);
968            break;
969        case IDL_DT_RANGE:
970            IDL_GET_RANGE_FROM_VECTOR( range_bounds, defn_vec_ptr );
971            rpc_ss_ndr_marsh_bounded_scalar( &range_bounds, *defn_vec_ptr,
972                                             transmitted_data, IDL_msp );
973            break;
974        default:
975#ifdef DEBUG_INTERP
976            printf("rpc_ss_ndr_marsh_xmit_as: unrecognized type %d\n",
977                        transmitted_type);
978            exit(0);
979#endif
980            DCETHREAD_RAISE(rpc_x_coding_error);
981
982    }
983
984    /* Release storage for transmitted type */
985    (IDL_msp->IDL_m_xmit_level)--;
986    (*(routine_ptr+IDL_RTN_FREE_XMIT_INDEX))(transmitted_data);
987
988    /* On server side, release targets of any pointers in presented type.
989        If this is a recursive call, the "presented type" is freed by
990        the "FREE_XMIT" above as the stack unwinds */
991    if ((IDL_msp->IDL_side == IDL_server_side_k)
992        && (IDL_msp->IDL_m_xmit_level == 0))
993    {
994        (*(routine_ptr+IDL_RTN_FREE_INST_INDEX))(param_addr);
995    }
996}
997
998/******************************************************************************/
999/*                                                                            */
1000/*  Marshall a context handle                                                 */
1001/*                                                                            */
1002/******************************************************************************/
1003void rpc_ss_ndr_marsh_context
1004(
1005    /* [in] */ idl_byte context_type,
1006                                    /* Need to know directionality of context */
1007    /* [in] */ rpc_void_p_t param_addr,
1008    IDL_msp_t IDL_msp
1009)
1010{
1011    ndr_context_handle wire_format;
1012    ndr_context_handle *p_wire_format;
1013    int i;
1014
1015    if (IDL_msp->IDL_side == IDL_client_side_k)
1016    {
1017        /* Convert context to wire form */
1018        rpc_ss_er_ctx_to_wire( *(rpc_ss_context_t *)param_addr, &wire_format,
1019                               IDL_msp->IDL_h,
1020                               (context_type == IDL_DT_IN_OUT_CONTEXT),
1021                               &IDL_msp->IDL_status );
1022        p_wire_format = &wire_format;
1023    }
1024    else
1025        p_wire_format = &((IDL_ee_context_t *)param_addr)->wire;
1026
1027    rpc_ss_ndr_marsh_scalar(IDL_DT_ULONG,
1028                         &p_wire_format->context_handle_attributes, IDL_msp);
1029    rpc_ss_ndr_marsh_scalar(IDL_DT_ULONG,
1030                         &p_wire_format->context_handle_uuid.time_low, IDL_msp);
1031    IDL_MARSH_CUSHORT(&p_wire_format->context_handle_uuid.time_mid);
1032    IDL_MARSH_CUSHORT(&p_wire_format->context_handle_uuid.time_hi_and_version);
1033    IDL_MARSH_CUSMALL(&p_wire_format->context_handle_uuid.clock_seq_hi_and_reserved);
1034    IDL_MARSH_CUSMALL(&p_wire_format->context_handle_uuid.clock_seq_low);
1035    for (i=0; i<6; i++)
1036    {
1037        rpc_ss_ndr_marsh_scalar(IDL_DT_BYTE,
1038                    &p_wire_format->context_handle_uuid.node[i], IDL_msp);
1039    }
1040}
1041
1042/******************************************************************************/
1043/*                                                                            */
1044/*  Marshall a [v1_string]                                                    */
1045/*                                                                            */
1046/******************************************************************************/
1047void rpc_ss_ndr_marsh_v1_string
1048(
1049    /* [in] */ rpc_void_p_t param_addr,
1050    /* [in] */ idl_ulong_int flags,
1051    IDL_msp_t IDL_msp
1052)
1053{
1054    idl_ushort_int actual_count;    /* See NDR spec */
1055    idl_byte dummy_defn_vec = IDL_DT_CHAR;  /* [v1_string] always of char */
1056    IDL_bound_pair_t bounds_list;  /* Bounds of array data */
1057
1058    actual_count = strlen((char *)param_addr);
1059    IDL_MARSH_CUSHORT(&actual_count);
1060    bounds_list.lower = 0;
1061    bounds_list.upper = actual_count;
1062    rpc_ss_ndr_m_fix_or_conf_arr(param_addr, 1, &bounds_list, &dummy_defn_vec,
1063                                 flags, IDL_msp);
1064}
1065