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**  NAME
79**
80**     cs_s_stub.c
81**
82**  FACILITY:
83**
84**     Remote Procedure Call (RPC)
85**     I18N Character Call   (RPC)
86**
87**  ABSTRACT:
88**
89**
90*/
91#include <commonp.h>		/* include nbase.h lbase.h internally	*/
92#include <ns.h>
93#include <com.h>
94#include <nsp.h>
95#include <dce/idlbase.h>	/* definitions for idl_cs_* 		*/
96#include <dce/rpcsts.h>
97#include <codesets.h>		/* Data definitions for I18N NSI
98							sub-component   */
99#include <dce/codesets_stub.h>	/* Stub support routines */
100
101#include <stdio.h>		/* definition of NULL			*/
102#include <stdlib.h>		/* definition of MB_CUR_MAX		*/
103#include <langinfo.h>		/* definition of nl_langinfo routine	*/
104
105#include <codesets.h>
106#include <cs_s.h>		/* Private defs for code set interoperability */
107
108
109/*
110**++
111**  ROUTINE NAME:       cs_byte_to_netcs
112**
113**  SCOPE:              PUBLIC - declared in dce/codesets_stub.h
114**
115**  DESCRIPTION:
116**
117**  Convert an encoding of a local data to network encoding, based on
118**  the information from a tag.
119**
120**  INPUTS:
121**
122**      h		Binding handle
123**
124**      tag		Identifies the code set that will be used on the wire.
125**
126**	ldata		Address of the local data.
127**
128**      l_data_len	The number of "byte" data elements to be processed.
129**
130**  OUTPUTS:
131**
132**	wdata		Address to which the converted data is to be written.
133**
134**	p_w_data_len	NULL if fixed array is being marshalled.
135**			The address to which the routine writes the
136**			on-the-wire data length.
137**
138**      status          The status of the operation.
139**                      Can be one of:
140**                          rpc_s_ok
141**                          rpc_ss_incompatible_codesets
142**                      or a status returned from a called routine.
143**
144**  IMPLICIT INPUTS:    none
145**
146**  IMPLICIT OUTPUTS:   none
147**
148**  FUNCTION VALUE:     void
149**
150**  SIDE EFFECTS:       none
151**
152**--
153*/
154
155PUBLIC void cs_byte_to_netcs
156(
157	rpc_binding_handle_t	h,
158	unsigned32		tag,
159	idl_byte		*ldata,
160	unsigned32		l_data_len,
161	idl_byte		*wdata,
162	unsigned32		*p_w_data_len,
163	error_status_t		*status
164)
165{
166	char			*current_codeset;
167	unsigned32		current_rgy_codeset;
168	int			i;
169	idl_byte		*wdata_temp, *ldata_temp;
170
171	rpc_cs_method_eval_p_t	method_p;
172	rpc_cs_tags_eval_p_t	tags_p;
173	rpc_binding_rep_p_t 	bind_p;
174
175	bind_p = (rpc_binding_rep_p_t)h;
176	if (!RPC_BINDING_IS_SERVER (bind_p))
177	{
178		switch (bind_p->cs_eval.key)
179		{
180		case RPC_CS_EVAL_METHOD:
181			method_p = &bind_p->cs_eval.tagged_union.method_key;
182
183			switch (method_p->method)
184			{
185			case RPC_EVAL_NO_CONVERSION:
186			case RPC_EVAL_RMIR_MODEL:
187			case RPC_EVAL_SMIR_MODEL:
188				wdata_temp = wdata;
189				ldata_temp = ldata;
190				for (i=0; i<= l_data_len; i++)
191					*wdata_temp++ = *ldata_temp++;
192
193				if (p_w_data_len != NULL)
194				{
195					*p_w_data_len = strlen((char *)wdata) + 1;
196				}
197
198				*status = rpc_s_ok;
199				break;
200
201			case RPC_EVAL_CMIR_MODEL:
202			case RPC_EVAL_INTERMEDIATE_MODEL:
203			case RPC_EVAL_UNIVERSAL_MODEL:
204
205				stub_conversion (
206					h,
207					RPC_BINDING_IS_SERVER (bind_p),
208					method_p->tags.client_tag,
209					tag,
210					ldata,
211					l_data_len,
212					wdata,
213					p_w_data_len,
214					status );
215
216				if (p_w_data_len != NULL)
217				{
218					*p_w_data_len = strlen((char *)wdata) + 1;
219				}
220
221				break;
222
223			default:
224				*status = rpc_s_ss_incompatible_codesets;
225				break;
226
227			}
228			break;
229
230		case RPC_CS_EVAL_TAGS:
231
232			tags_p = &bind_p->cs_eval.tagged_union.tags_key;
233
234			/*
235			 * Determine the conversion type.
236			 */
237			if (tag == tags_p->client_tag)
238					/* No conversion required */
239			{
240				wdata_temp = wdata;
241				ldata_temp = ldata;
242				for (i=0; i<= l_data_len; i++)
243					*wdata_temp++ = *ldata_temp++;
244
245				if (p_w_data_len != NULL)
246				{
247					*p_w_data_len = strlen((char *)wdata) + 1;
248				}
249
250				*status = rpc_s_ok;
251			}
252			else
253			{
254				stub_conversion (
255					h,
256					RPC_BINDING_IS_SERVER (bind_p),
257					tags_p->client_tag,
258					tag,
259					ldata,
260					l_data_len,
261					wdata,
262					p_w_data_len,
263					status );
264
265				if (p_w_data_len != NULL)
266				{
267					*p_w_data_len = strlen((char *)wdata) + 1;
268				}
269			}
270			break;
271
272		default:
273			*status = rpc_s_ss_incompatible_codesets;
274			break;
275		}
276	}
277	else	/* server side */
278	{
279		/*
280		 * Get the code set info from the current locale.
281		 */
282		current_codeset = nl_langinfo(CODESET);
283		dce_cs_loc_to_rgy(
284			(unsigned_char_p_t)current_codeset,
285			&current_rgy_codeset,
286			NULL, NULL,
287			status);
288
289		if (*status != dce_cs_c_ok)
290		{
291			/* codeset registry error */
292			*status = rpc_s_ok;
293			return;
294		}
295		/*
296		 * Determine the conversion type.
297		 */
298		if (tag == current_rgy_codeset)
299				/* No conversion required */
300		{
301			wdata_temp = wdata;
302			ldata_temp = ldata;
303			for (i=0; i<= l_data_len; i++)
304				*wdata_temp++ = *ldata_temp++;
305
306			if (p_w_data_len != NULL)
307			{
308				*p_w_data_len = strlen((char *)wdata) + 1;
309			}
310
311			*status = rpc_s_ok;
312		}
313		else
314		{
315			stub_conversion (
316				h,
317				RPC_BINDING_IS_SERVER (bind_p),
318				current_rgy_codeset,
319				tag,
320				ldata,
321				l_data_len,
322				wdata,
323				p_w_data_len,
324				status );
325
326			if (p_w_data_len != NULL)
327			{
328				*p_w_data_len = strlen((char *)wdata) + 1;
329			}
330		}
331	}
332	return;
333}
334
335
336/*
337**++
338**  ROUTINE NAME:       wchar_t_to_netcs
339**
340**  SCOPE:              PUBLIC - declared in dce/codesets_stub.h
341**
342**  DESCRIPTION:
343**
344**  Convert an encoding of a local data to network encoding, based on
345**  the information from a tag.
346**
347**  INPUTS:
348**
349**      h		Binding handle
350**
351**      tag		Identifies the code set that will be used on the wire.
352**
353**	ldata		Address of the local data.
354**
355**      l_data_len	The number of "byte" data elements to be processed.
356**
357**  OUTPUTS:
358**
359**	wdata		Address to which the converted data is to be written.
360**
361**	p_w_data_len	NULL if fixed array is being marshalled.
362**			The address to which the routine writes the
363**			on-the-wire data length.
364**
365**      status          The status of the operation.
366**                      Can be one of:
367**                          rpc_s_ok
368**                          rpc_ss_incompatible_codesets
369**                      or a status returned from a called routine.
370**
371**  IMPLICIT INPUTS:    none
372**
373**  IMPLICIT OUTPUTS:   none
374**
375**  FUNCTION VALUE:     void
376**
377**  SIDE EFFECTS:       none
378**
379**--
380*/
381
382PUBLIC void wchar_t_to_netcs
383(
384	rpc_binding_handle_t	h,
385	unsigned32		tag,
386	wchar_t			*ldata,
387	unsigned32		l_data_len,
388	idl_byte		*wdata,
389	unsigned32		*p_w_data_len,
390	error_status_t		*status
391)
392{
393	char			*current_codeset;
394	unsigned32		current_rgy_codeset;
395	idl_byte		*byte_ldata;
396	idl_byte		*t_byte_ldata;
397	size_t			ldata_length;
398	size_t			conv_ret;
399	int			i;
400	idl_byte		*wdata_temp, *ldata_temp;
401
402	rpc_cs_method_eval_p_t	method_p;
403	rpc_cs_tags_eval_p_t	tags_p;
404	rpc_binding_rep_p_t 	bind_p;
405
406	/*
407	 *  Allocate the largest buffer for the conversion.
408	 */
409	ldata_length = l_data_len * MB_CUR_MAX + MB_CUR_MAX;
410
411	RPC_MEM_ALLOC (
412		byte_ldata,
413		unsigned_char_p_t,
414		ldata_length,
415		RPC_C_MEM_STRING,
416		RPC_C_MEM_WAITOK);
417
418	/* Initialize the buffer */
419	t_byte_ldata = byte_ldata;
420	i = ldata_length;
421	while (i--)
422		*t_byte_ldata++ = '\0';
423
424	conv_ret = wcstombs((char *)byte_ldata, ldata, ldata_length);
425
426	if (conv_ret == -1)		/* Conversion error took place */
427	{
428		*status = rpc_s_ss_invalid_char_input;
429		RPC_MEM_FREE(byte_ldata, RPC_C_MEM_STRING);
430		return;
431	}
432
433	bind_p = (rpc_binding_rep_p_t)h;
434	if (!RPC_BINDING_IS_SERVER (bind_p))
435	{
436		switch (bind_p->cs_eval.key)
437		{
438		case RPC_CS_EVAL_METHOD:
439			method_p = &bind_p->cs_eval.tagged_union.method_key;
440
441			switch (method_p->method)
442			{
443			case RPC_EVAL_NO_CONVERSION:
444			case RPC_EVAL_RMIR_MODEL:
445			case RPC_EVAL_SMIR_MODEL:
446				wdata_temp = wdata;
447				ldata_temp = byte_ldata;
448				for (i=0; i<= conv_ret; i++)
449					*wdata_temp++ = *ldata_temp++;
450
451				if (p_w_data_len != NULL)
452					*p_w_data_len = conv_ret;
453
454				*status = rpc_s_ok;
455				break;
456
457			case RPC_EVAL_CMIR_MODEL:
458			case RPC_EVAL_INTERMEDIATE_MODEL:
459			case RPC_EVAL_UNIVERSAL_MODEL:
460				stub_conversion (
461					h,
462					RPC_BINDING_IS_SERVER (bind_p),
463					method_p->tags.client_tag,
464					tag,
465					byte_ldata,
466					conv_ret,
467					wdata,
468					p_w_data_len,
469					status );
470				break;
471
472			default:
473				*status = rpc_s_ss_incompatible_codesets;
474				break;
475
476			}
477			break;
478
479		case RPC_CS_EVAL_TAGS:
480			tags_p = &bind_p->cs_eval.tagged_union.tags_key;
481
482			/*
483			 * Determine the conversion type.
484			 */
485			if (tag == tags_p->client_tag)
486					/* No conversion required */
487			{
488				wdata_temp = wdata;
489				ldata_temp = byte_ldata;
490				for (i=0; i<= conv_ret; i++)
491					*wdata_temp++ = *ldata_temp++;
492
493				if (p_w_data_len != NULL)
494					*p_w_data_len = conv_ret;
495
496				*status = rpc_s_ok;
497			}
498			else
499			{
500				stub_conversion (
501					h,
502					RPC_BINDING_IS_SERVER (bind_p),
503					tags_p->client_tag,
504					tag,
505					byte_ldata,
506					conv_ret,
507					wdata,
508					p_w_data_len,
509					status );
510			}
511			break;
512
513		default:
514			*status = rpc_s_ss_incompatible_codesets;
515			break;
516		}
517	}
518	else	/* server side */
519	{
520		/*
521		 * Get the code set info from the current locale.
522		 */
523		current_codeset = nl_langinfo(CODESET);
524		dce_cs_loc_to_rgy(
525			(unsigned_char_p_t)current_codeset,
526			&current_rgy_codeset,
527			NULL, NULL,
528			status);
529
530		if (*status != dce_cs_c_ok)
531		{
532			/* codeset registry error */
533			*status = rpc_s_ok;
534			RPC_MEM_FREE(byte_ldata, RPC_C_MEM_STRING);
535			return;
536		}
537		/*
538		 * Determine the conversion type.
539		 */
540		if (tag == current_rgy_codeset)
541				/* No conversion required */
542		{
543			wdata_temp = wdata;
544			ldata_temp = byte_ldata;
545			for (i=0; i<= conv_ret; i++)
546				*wdata_temp++ = *ldata_temp++;
547
548			if (p_w_data_len != NULL)
549				*p_w_data_len = conv_ret;
550
551			*status = rpc_s_ok;
552		}
553		else
554		{
555			stub_conversion (
556				h,
557				RPC_BINDING_IS_SERVER (bind_p),
558				current_rgy_codeset,
559				tag,
560				byte_ldata,
561				conv_ret,
562				wdata,
563				p_w_data_len,
564				status );
565		}
566	}
567	RPC_MEM_FREE(byte_ldata, RPC_C_MEM_STRING);
568	return;
569}
570
571
572/*
573**++
574**  ROUTINE NAME:       cs_byte_from_netcs
575**
576**  SCOPE:              PUBLIC - declared in dce/codesets_stub.h
577**
578**  DESCRIPTION:
579**
580**  Convert an encoding of a network data to local encoding, based on
581**  the information from a tag.
582**
583**  INPUTS:
584**
585**      h		Binding handle
586**
587**      tag		Identifies the code set that will be used on the wire.
588**
589**	wdata		Address of the network data.
590**
591**      w_data_len	The number of "byte" data elements to be processed.
592**
593**  OUTPUTS:
594**
595**	ldata		Address to which the converted data is to be written.
596**
597**	p_l_data_len	NULL if fixed array is being marshalled.
598**			The address to which the routine writes the
599**			local data length.
600**
601**      status          The status of the operation.
602**                      Can be one of:
603**                          rpc_s_ok
604**                          rpc_ss_incompatible_codesets
605**                      or a status returned from a called routine.
606**
607**  IMPLICIT INPUTS:    none
608**
609**  IMPLICIT OUTPUTS:   none
610**
611**  FUNCTION VALUE:     void
612**
613**  SIDE EFFECTS:       none
614**
615**--
616*/
617
618PUBLIC void cs_byte_from_netcs
619(
620	rpc_binding_handle_t	h,
621	unsigned32		tag,
622	idl_byte		*wdata,
623	unsigned32		w_data_len,
624	unsigned32		l_storage_len,
625	idl_byte		*ldata,
626	unsigned32		*p_l_data_len,
627	error_status_t		*status
628)
629{
630	char			*current_codeset;
631	unsigned32		current_rgy_codeset;
632	int			i;
633	idl_byte		*wdata_temp, *ldata_temp;
634
635	rpc_cs_method_eval_p_t	method_p;
636	rpc_cs_tags_eval_p_t	tags_p;
637	rpc_binding_rep_p_t 	bind_p;
638
639	bind_p = (rpc_binding_rep_p_t)h;
640	if (!RPC_BINDING_IS_SERVER (bind_p))
641	{
642		switch (bind_p->cs_eval.key)
643		{
644		case RPC_CS_EVAL_METHOD:
645			method_p = &bind_p->cs_eval.tagged_union.method_key;
646
647			switch (method_p->method)
648			{
649			case RPC_EVAL_NO_CONVERSION:
650			case RPC_EVAL_SMIR_MODEL:
651				wdata_temp = wdata;
652				ldata_temp = ldata;
653				for (i=0; i<= w_data_len; i++)
654					*wdata_temp++ = *ldata_temp++;
655
656				if (p_l_data_len != NULL)
657				{
658					*p_l_data_len = strlen((char *)wdata) + 1;
659				}
660
661				*status = rpc_s_ok;
662				break;
663
664			case RPC_EVAL_CMIR_MODEL:
665			case RPC_EVAL_RMIR_MODEL:
666			case RPC_EVAL_INTERMEDIATE_MODEL:
667			case RPC_EVAL_UNIVERSAL_MODEL:
668				stub_conversion (
669					h,
670					RPC_BINDING_IS_SERVER (bind_p),
671					tag,
672					method_p->tags.client_tag,
673					wdata,
674					w_data_len,
675					ldata,
676					p_l_data_len,
677					status );
678
679				if (p_l_data_len != NULL)
680				{
681					*p_l_data_len = strlen((char *)wdata) + 1;
682				}
683
684				break;
685
686			default:
687				*status = rpc_s_ss_incompatible_codesets;
688				break;
689
690			}
691			break;
692
693		case RPC_CS_EVAL_TAGS:
694			tags_p = &bind_p->cs_eval.tagged_union.tags_key;
695
696			/*
697			 * Determine the conversion type.
698			 */
699			if (tag == tags_p->client_tag)
700					/* No conversion required */
701			{
702				wdata_temp = wdata;
703				ldata_temp = ldata;
704				for (i=0; i<= w_data_len; i++)
705					*wdata_temp++ = *ldata_temp++;
706
707				if (p_l_data_len != NULL)
708				{
709					*p_l_data_len = strlen((char *)wdata) + 1;
710				}
711
712				*status = rpc_s_ok;
713			}
714			else
715			{
716				stub_conversion (
717					h,
718					RPC_BINDING_IS_SERVER (bind_p),
719					tag,
720					tags_p->client_tag,
721					wdata,
722					w_data_len,
723					ldata,
724					p_l_data_len,
725					status );
726
727				if (p_l_data_len != NULL)
728				{
729					*p_l_data_len = strlen((char *)wdata) + 1;
730				}
731			}
732			break;
733
734		default:
735			*status = rpc_s_ss_incompatible_codesets;
736			break;
737		}
738	}
739	else	/* server side */
740	{
741		/*
742		 * Get the code set info from the current locale.
743		 */
744		current_codeset = nl_langinfo(CODESET);
745		dce_cs_loc_to_rgy(
746			(unsigned_char_p_t)current_codeset,
747			&current_rgy_codeset,
748			NULL, NULL,
749			status);
750
751		if (*status != dce_cs_c_ok)
752		{
753			/* codeset registry error */
754			*status = rpc_s_ok;
755			return;
756		}
757		/*
758		 * Determine the conversion type.
759		 */
760		if (tag == current_rgy_codeset)
761				/* No conversion required */
762		{
763			wdata_temp = wdata;
764			ldata_temp = ldata;
765			for (i=0; i<= w_data_len; i++)
766				*wdata_temp++ = *ldata_temp++;
767
768			if (p_l_data_len != NULL)
769			{
770				*p_l_data_len = strlen((char *)wdata) + 1;
771			}
772
773			*status = rpc_s_ok;
774		}
775		else
776		{
777			stub_conversion (
778				h,
779				RPC_BINDING_IS_SERVER (bind_p),
780				tag,
781				current_rgy_codeset,
782				wdata,
783				w_data_len,
784				ldata,
785				p_l_data_len,
786				status );
787
788			if (p_l_data_len != NULL)
789			{
790				*p_l_data_len = strlen((char *)wdata) + 1;
791			}
792		}
793	}
794	return;
795}
796
797
798/*
799**++
800**  ROUTINE NAME:       wchar_t_from_netcs
801**
802**  SCOPE:              PUBLIC - declared in dce/codesets_stub.h
803**
804**  DESCRIPTION:
805**
806**  Convert an encoding of a network data to local encoding, based on
807**  the information from a tag.
808**
809**  INPUTS:
810**
811**      h		Binding handle
812**
813**      tag		Identifies the code set that will be used on the wire.
814**
815**	wdata		Address of the network data.
816**
817**      w_data_len	The number of "byte" data elements to be processed.
818**
819**  OUTPUTS:
820**
821**	ldata		Address to which the converted data is to be written.
822**
823**	p_l_data_len	NULL if fixed array is being marshalled.
824**			The address to which the routine writes the
825**			local data length.
826**
827**      status          The status of the operation.
828**                      Can be one of:
829**                          rpc_s_ok
830**                          rpc_ss_incompatible_codesets
831**                      or a status returned from a called routine.
832**
833**  IMPLICIT INPUTS:    none
834**
835**  IMPLICIT OUTPUTS:   none
836**
837**  FUNCTION VALUE:     void
838**
839**  SIDE EFFECTS:       none
840**
841**--
842*/
843
844PUBLIC void wchar_t_from_netcs
845(
846	rpc_binding_handle_t	h,
847	unsigned32		tag,
848	idl_byte		*wdata,
849	unsigned32		w_data_len,
850	unsigned32		l_storage_len,
851	wchar_t			*ldata,
852	unsigned32		*p_l_data_len,
853	error_status_t		*status
854)
855{
856	char			*current_codeset;
857	unsigned32		current_rgy_codeset;
858	idl_byte		*byte_wdata;
859	idl_byte		*t_byte_wdata;
860	size_t			wdata_length;
861	size_t			conv_length;
862	int			i;
863	idl_byte		*ldata_temp;
864
865	rpc_cs_method_eval_p_t	method_p;
866	rpc_cs_tags_eval_p_t	tags_p;
867	rpc_binding_rep_p_t 	bind_p;
868
869	bind_p = (rpc_binding_rep_p_t)h;
870	if (!RPC_BINDING_IS_SERVER (bind_p))
871	{
872		switch (bind_p->cs_eval.key)
873		{
874		case RPC_CS_EVAL_METHOD:
875			method_p = &bind_p->cs_eval.tagged_union.method_key;
876
877			switch (method_p->method)
878			{
879			case RPC_EVAL_NO_CONVERSION:
880			case RPC_EVAL_SMIR_MODEL:
881
882        			wdata_length = mbstowcs(ldata, (char *)wdata, (size_t)w_data_len);
883				if (wdata_length == -1)
884					/* Conversion error took place */
885					*status = rpc_s_ss_invalid_char_input;
886				else
887					*status = rpc_s_ok;
888
889				if (p_l_data_len != NULL)
890					*p_l_data_len = wdata_length;
891				break;
892
893			case RPC_EVAL_CMIR_MODEL:
894			case RPC_EVAL_RMIR_MODEL:
895			case RPC_EVAL_INTERMEDIATE_MODEL:
896			case RPC_EVAL_UNIVERSAL_MODEL:
897
898				RPC_MEM_ALLOC (
899					byte_wdata,
900					unsigned_char_p_t,
901					w_data_len,
902					RPC_C_MEM_STRING,
903					RPC_C_MEM_WAITOK);
904
905				/* initialize the buffer */
906				t_byte_wdata = byte_wdata;
907				i = l_storage_len;
908				while (i--)
909					*t_byte_wdata++ = L'\0';
910
911				stub_conversion (
912					h,
913					RPC_BINDING_IS_SERVER (bind_p),
914					tag,
915					method_p->tags.client_tag,
916					wdata,
917					w_data_len,
918					byte_wdata,	/* ldata, */
919					(unsigned32 *)&wdata_length, /* p_l_data_len,*/
920					status );
921
922				wdata_length = mbstowcs(ldata, (char *)byte_wdata, (size_t)w_data_len);
923				if (wdata_length == -1)
924					/* Conversion error took place */
925					*status = rpc_s_ss_invalid_char_input;
926				else
927				{
928					if (p_l_data_len != NULL)
929						*p_l_data_len = wdata_length;
930
931					*status = rpc_s_ok;
932				}
933
934				RPC_MEM_FREE(byte_wdata, RPC_C_MEM_STRING);
935
936				break;
937
938			default:
939				*status = rpc_s_ss_incompatible_codesets;
940				break;
941
942			}
943			break;
944
945		case RPC_CS_EVAL_TAGS:
946			tags_p = &bind_p->cs_eval.tagged_union.tags_key;
947
948			if (tag == tags_p->client_tag)
949					/* No conversion required */
950			{
951        			wdata_length = mbstowcs(ldata, (char *)wdata, (size_t)w_data_len);
952				if (wdata_length == -1)
953					/* Conversion error took place */
954					*status = rpc_s_ss_invalid_char_input;
955				else
956					*status = rpc_s_ok;
957
958				if (p_l_data_len != NULL)
959					*p_l_data_len = wdata_length;
960			}
961			else
962			{
963				RPC_MEM_ALLOC (
964					byte_wdata,
965					unsigned_char_p_t,
966					w_data_len,
967					RPC_C_MEM_STRING,
968					RPC_C_MEM_WAITOK);
969
970				/* initialize the buffer */
971				t_byte_wdata = byte_wdata;
972				i = w_data_len;
973				while (i--)
974					*t_byte_wdata++ = L'\0';
975
976				stub_conversion (
977					h,
978					RPC_BINDING_IS_SERVER (bind_p),
979					tag,
980					tags_p->client_tag,
981					wdata,
982					w_data_len,
983					byte_wdata,	/* ldata, */
984					(unsigned32 *)&wdata_length, /* p_l_data_len,*/
985					status );
986
987				wdata_length = mbstowcs(ldata, (char *)byte_wdata, (size_t)w_data_len);
988				if (wdata_length == -1)
989					/* Conversion error took place */
990					*status = rpc_s_ss_invalid_char_input;
991				else
992				{
993					if (p_l_data_len != NULL)
994						*p_l_data_len = wdata_length;
995
996					*status = rpc_s_ok;
997				}
998
999				RPC_MEM_FREE(byte_wdata, RPC_C_MEM_STRING);
1000
1001			}
1002			break;
1003
1004		default:
1005			*status = rpc_s_ss_incompatible_codesets;
1006			break;
1007		}
1008	}
1009	else	/* server side */
1010	{
1011		/*
1012		 * Get the code set info from the current locale.
1013		 */
1014		current_codeset = nl_langinfo(CODESET);
1015		dce_cs_loc_to_rgy(
1016			(unsigned_char_p_t)current_codeset,
1017			&current_rgy_codeset,
1018			NULL, NULL,
1019			status);
1020
1021		if (*status != dce_cs_c_ok)
1022		{
1023			/* codeset registry error */
1024			*status = rpc_s_ok;
1025			return;
1026		}
1027		/*
1028		 * Determine the conversion type.
1029		 */
1030		if (tag == current_rgy_codeset)
1031				/* No conversion required */
1032		{
1033        		wdata_length = mbstowcs(ldata, (char *)wdata, (size_t)w_data_len);
1034			if (wdata_length == -1)
1035				/* Conversion error took place */
1036				*status = rpc_s_ss_invalid_char_input;
1037			else
1038			{
1039				if (p_l_data_len != NULL)
1040					*p_l_data_len = wdata_length;
1041
1042				*status = rpc_s_ok;
1043			}
1044		}
1045		else
1046		{
1047			RPC_MEM_ALLOC (
1048				byte_wdata,
1049				unsigned_char_p_t,
1050				w_data_len,
1051				RPC_C_MEM_STRING,
1052				RPC_C_MEM_WAITOK);
1053
1054			/* initialize the buffer */
1055			t_byte_wdata = byte_wdata;
1056			i = w_data_len;
1057			while (i--)
1058				*t_byte_wdata++ = L'\0';
1059
1060			stub_conversion (
1061				h,
1062				RPC_BINDING_IS_SERVER (bind_p),
1063				tag,
1064				current_rgy_codeset,
1065				wdata,
1066				w_data_len,
1067				byte_wdata,	/* ldata, */
1068				(unsigned32 *)&wdata_length, /* p_l_data_len,*/
1069				status );
1070
1071			wdata_length = mbstowcs(ldata, (char *)byte_wdata, (size_t)w_data_len);
1072			if (wdata_length == -1)
1073				/* Conversion error took place */
1074				*status = rpc_s_ss_invalid_char_input;
1075			else
1076			{
1077				if (p_l_data_len != NULL)
1078					*p_l_data_len = wdata_length;
1079
1080				*status = rpc_s_ok;
1081			}
1082
1083			RPC_MEM_FREE(byte_wdata, RPC_C_MEM_STRING);
1084		}
1085	}
1086	return;
1087}
1088
1089
1090/*
1091**++
1092**  ROUTINE NAME:       cs_byte_net_size
1093**
1094**  SCOPE:              PUBLIC - declared in dce/codesets_stub.h
1095**
1096**  DESCRIPTION:
1097**
1098**  Calculate the necessary buffer size for code set converesion, based on
1099**  the information from a binding handle, tag, and local storage size.
1100**
1101**  INPUTS:
1102**
1103**      h		Binding handle
1104**
1105**      tag		Identifies the code set that will be used on the wire.
1106**			When the caller is a client stub, this is cs_stag value.
1107**			When the caller is a server stub, this is cs_rtag value.
1108**
1109**      l_storage_len	The size, in units of byte, of the local storage
1110**			allocated for the I-char data.  This is the local value
1111**			of the size_is variable for the array.
1112**
1113**  OUTPUTS:
1114**
1115**	p_convert_type	Indicate whether data conversion is necessary.
1116**			In case of  idl_cs_in_place_convert, l_storage_len
1117**			is assumed to be sufficient for the buffer size.
1118**
1119**	p_w_storage_len	NULL if fixed or varying array is being marshalled.
1120**			When conformant or conformant varying array is being
1121**			marshalled, and p_convert_type is idl_cs_new_buffer
1122**			convert, this is the storage size in units of idl_byte.
1123**
1124**      status          The status of the operation.
1125**                      Can be one of:
1126**                          rpc_s_ok
1127**                          rpc_ss_incompatible_codesets
1128**                      or a status returned from a called routine.
1129**
1130**  IMPLICIT INPUTS:    none
1131**
1132**  IMPLICIT OUTPUTS:   none
1133**
1134**  FUNCTION VALUE:     void
1135**
1136**  SIDE EFFECTS:       none
1137**
1138**--
1139*/
1140
1141PUBLIC void cs_byte_net_size
1142(
1143	rpc_binding_handle_t	h,
1144	unsigned32		tag,		/* wire encoding */
1145	unsigned32		l_storage_len,
1146	idl_cs_convert_t	*p_convert_type,
1147	unsigned32		*p_w_storage_len,
1148	error_status_t		*status
1149)
1150{
1151	char			*current_codeset;
1152	unsigned32		current_rgy_codeset;
1153	unsigned16		stag_bytes;
1154	unsigned16		client_bytes;
1155
1156	rpc_cs_method_eval_p_t	method_p;
1157	rpc_cs_tags_eval_p_t	tags_p;
1158	rpc_binding_rep_p_t 	bind_p;
1159
1160	bind_p = (rpc_binding_rep_p_t)h;
1161	if (!RPC_BINDING_IS_SERVER (bind_p))
1162	{
1163		switch (bind_p->cs_eval.key)
1164		{
1165		case RPC_CS_EVAL_METHOD:
1166			method_p = &bind_p->cs_eval.tagged_union.method_key;
1167
1168			if (method_p->tags.type_handle != NULL)
1169			{
1170				if ((idl_cs_convert_t)method_p->tags.type_handle
1171						==  idl_cs_no_convert ||
1172				    (idl_cs_convert_t)method_p->tags.type_handle
1173						==  idl_cs_in_place_convert)
1174				{
1175
1176					*p_convert_type = (idl_cs_convert_t)
1177							method_p->tags.type_handle;
1178					if (p_w_storage_len != NULL)
1179				   		*p_w_storage_len = l_storage_len;
1180					*status = rpc_s_ok;
1181
1182				}
1183				else if ((idl_cs_convert_t)
1184					method_p->tags.type_handle
1185						==  idl_cs_new_buffer_convert)
1186				{
1187					*p_convert_type = (idl_cs_convert_t)
1188							method_p->tags.type_handle;
1189
1190					if (p_w_storage_len != NULL)
1191					   *p_w_storage_len
1192						= l_storage_len *
1193						     method_p->tags.stag_max_bytes;
1194					*status = rpc_s_ok;
1195
1196				}
1197			}
1198			else
1199			{
1200				switch (method_p->method)
1201				{
1202				case RPC_EVAL_NO_CONVERSION:
1203				case RPC_EVAL_RMIR_MODEL:
1204				case RPC_EVAL_SMIR_MODEL:
1205					*p_convert_type = idl_cs_no_convert;
1206					if (p_w_storage_len != NULL)
1207					   *p_w_storage_len = l_storage_len;
1208
1209					if (method_p->fixed)
1210					    method_p->tags.type_handle
1211						= (rpc_ns_handle_t)*p_convert_type;
1212
1213					*status = rpc_s_ok;
1214					break;
1215
1216				case RPC_EVAL_CMIR_MODEL:
1217				case RPC_EVAL_INTERMEDIATE_MODEL:
1218				case RPC_EVAL_UNIVERSAL_MODEL:
1219
1220					if ((method_p->fixed) &&
1221					    (method_p->tags.stag_max_bytes ==
1222					       method_p->tags.client_max_bytes))
1223					{
1224						*p_convert_type =
1225							idl_cs_in_place_convert;
1226					        if (p_w_storage_len != NULL)
1227						     *p_w_storage_len = l_storage_len;
1228					}
1229					else if ( method_p->tags.stag_max_bytes ==
1230					       method_p->client->codesets[0].c_max_bytes)
1231					{
1232						*p_convert_type =
1233							idl_cs_in_place_convert;
1234					        if (p_w_storage_len != NULL)
1235						     *p_w_storage_len = l_storage_len;
1236					}
1237					else
1238					{
1239					    *p_convert_type
1240					        = idl_cs_new_buffer_convert;
1241					    if (p_w_storage_len != NULL)
1242                            *p_w_storage_len = l_storage_len
1243						      * method_p->tags.stag_max_bytes;
1244					}
1245					*status = rpc_s_ok;
1246
1247					if (method_p->fixed)
1248					    method_p->tags.type_handle
1249					     = (rpc_ns_handle_t)*p_convert_type;
1250					break;
1251
1252				default:
1253					*status = rpc_s_ss_incompatible_codesets;
1254					break;
1255
1256				}
1257			}
1258			break;
1259
1260		case RPC_CS_EVAL_TAGS:
1261			tags_p = &bind_p->cs_eval.tagged_union.tags_key;
1262
1263			if (tags_p->type_handle != NULL)
1264			{
1265				if ((idl_cs_convert_t)tags_p->type_handle
1266							== idl_cs_no_convert ||
1267				(idl_cs_convert_t)tags_p->type_handle
1268							== idl_cs_in_place_convert)
1269				{
1270					*p_convert_type = (idl_cs_convert_t)
1271							    tags_p->type_handle;
1272
1273					if (p_w_storage_len != NULL)
1274				   		*p_w_storage_len = l_storage_len;
1275					*status = rpc_s_ok;
1276
1277				}
1278				else if ((idl_cs_convert_t)tags_p->type_handle
1279						== idl_cs_new_buffer_convert)
1280				{
1281					*p_convert_type = (idl_cs_convert_t)
1282							tags_p->type_handle;
1283
1284					if (p_w_storage_len != NULL)
1285					   *p_w_storage_len =
1286					       l_storage_len * tags_p->stag_max_bytes;
1287
1288					*status = rpc_s_ok;
1289				}
1290			}
1291			else
1292			{
1293				/*
1294				 * Determine the conversion type.
1295				 */
1296				if (tag == tags_p->client_tag)
1297						/* No conversion required */
1298				{
1299					*p_convert_type = idl_cs_no_convert;
1300					if (p_w_storage_len != NULL)
1301						*p_w_storage_len = l_storage_len;
1302				}
1303				else
1304				{
1305					if (tags_p->stag_max_bytes ==
1306						tags_p->client_max_bytes)
1307
1308					{
1309						*p_convert_type =
1310							idl_cs_in_place_convert;
1311
1312					     if (p_w_storage_len != NULL)
1313						     *p_w_storage_len = l_storage_len;
1314					}
1315					else
1316					{
1317						*p_convert_type =
1318							idl_cs_new_buffer_convert;
1319						if (p_w_storage_len != NULL)
1320                            *p_w_storage_len =
1321							l_storage_len * tags_p->stag_max_bytes;
1322					}
1323
1324				}
1325				*status = rpc_s_ok;
1326
1327				tags_p->type_handle = (rpc_ns_handle_t)
1328							*p_convert_type;
1329			}
1330			break;
1331
1332		default:
1333			*status = rpc_s_ss_incompatible_codesets;
1334			break;
1335		}
1336	}
1337	else	/* Server side */
1338	{
1339		/*
1340		 * Get the code set info from the current locale.
1341		 */
1342		current_codeset = nl_langinfo(CODESET);
1343		dce_cs_loc_to_rgy(
1344			(unsigned_char_p_t)current_codeset,
1345			&current_rgy_codeset,
1346			NULL, NULL,
1347			status);
1348
1349		if (*status != dce_cs_c_ok)
1350		{
1351			/* codeset registry error */
1352			*status = rpc_s_ok;
1353			return;
1354		}
1355
1356		/*
1357		 * Determine the conversion type.
1358		 */
1359		if (tag == current_rgy_codeset)
1360				/* No conversion required */
1361		{
1362			*p_convert_type = idl_cs_no_convert;
1363			if (p_w_storage_len != NULL)
1364				*p_w_storage_len = l_storage_len;
1365
1366			*status = rpc_s_ok;
1367		}
1368		else
1369		{
1370			rpc_rgy_get_max_bytes (
1371				tag,
1372				&stag_bytes,
1373				status );
1374
1375			if (*status != rpc_s_ok)
1376				return;
1377
1378			rpc_rgy_get_max_bytes (
1379				current_rgy_codeset,
1380				&client_bytes,
1381				status );
1382
1383			if (*status != rpc_s_ok)
1384				return;
1385
1386			if (stag_bytes == client_bytes)
1387			{
1388				*p_convert_type = idl_cs_in_place_convert;
1389
1390				if (p_w_storage_len != NULL)
1391				     *p_w_storage_len = l_storage_len;
1392			}
1393			else
1394			{
1395				*p_convert_type = idl_cs_new_buffer_convert;
1396
1397				if (p_w_storage_len != NULL)
1398				    *p_w_storage_len = l_storage_len * stag_bytes;
1399			}
1400
1401			*status = rpc_s_ok;
1402		}
1403	}
1404	return;
1405}
1406
1407
1408/*
1409**++
1410**  ROUTINE NAME:       wchar_t_net_size
1411**
1412**  SCOPE:              PUBLIC - declared in dce/codesets_stub.h
1413**
1414**  DESCRIPTION:
1415**
1416**  Calculate the necessary buffer size for code set converesion, based on
1417**  the information from a binding handle, tag, and local storage size.
1418**
1419**  INPUTS:
1420**
1421**      h		Binding handle
1422**
1423**      tag		Identifies the code set that will be used on the wire.
1424**			When the caller is a client stub, this is cs_stag value.
1425**			When the caller is a server stub, this is cs_rtag value.
1426**
1427**      l_storage_len	The size, in units of byte, of the local storage
1428**			allocated for the I-char data.  This is the local value
1429**			of the size_is variable for the array.
1430**
1431**  OUTPUTS:
1432**
1433**	p_convert_type	Indicate whether data conversion is necessary.
1434**			In case of  idl_cs_in_place_convert, l_storage_len
1435**			is assumed to be sufficient for the buffer size.
1436**
1437**	p_w_storage_len	NULL if fixed or varying array is being marshalled.
1438**			When conformant or conformant varying array is being
1439**			marshalled, and p_convert_type is idl_cs_new_buffer
1440**			convert, this is the storage size in units of idl_byte.
1441**
1442**      status          The status of the operation.
1443**                      Can be one of:
1444**                          rpc_s_ok
1445**                          rpc_ss_incompatible_codesets
1446**                      or a status returned from a called routine.
1447**
1448**  IMPLICIT INPUTS:    none
1449**
1450**  IMPLICIT OUTPUTS:   none
1451**
1452**  FUNCTION VALUE:     void
1453**
1454**  SIDE EFFECTS:       none
1455**
1456**--
1457*/
1458
1459/*
1460**  We calculate the buffer size by multiplying the number of wchar_t by
1461**  the maximum bytes of wire encoding.
1462*/
1463
1464PUBLIC void wchar_t_net_size
1465(
1466	rpc_binding_handle_t	h,
1467	unsigned32		tag,			/* wire encoding */
1468	unsigned32		l_storage_len,		/* wchar_t length */
1469	idl_cs_convert_t	*p_convert_type,
1470	unsigned32		*p_w_storage_len,
1471	error_status_t		*status
1472)
1473{
1474	char			*current_codeset;
1475	unsigned32		current_rgy_codeset;
1476	unsigned16		stag_bytes;
1477	unsigned16		client_bytes;
1478
1479	rpc_cs_method_eval_p_t	method_p;
1480	rpc_cs_tags_eval_p_t	tags_p;
1481	rpc_binding_rep_p_t 	bind_p;
1482
1483	bind_p = (rpc_binding_rep_p_t)h;
1484	if (!RPC_BINDING_IS_SERVER (bind_p))
1485	{
1486		switch (bind_p->cs_eval.key)
1487		{
1488		case RPC_CS_EVAL_METHOD:
1489			method_p = &bind_p->cs_eval.tagged_union.method_key;
1490
1491			if (method_p->tags.type_handle != NULL)
1492			{
1493				*p_convert_type = (idl_cs_convert_t)
1494						method_p->tags.type_handle;
1495
1496				if (p_w_storage_len != NULL)
1497				   *p_w_storage_len = l_storage_len
1498					     		* sizeof(wchar_t);
1499				*status = rpc_s_ok;
1500
1501			}
1502			else
1503			{
1504				switch (method_p->method)
1505				{
1506				case RPC_EVAL_NO_CONVERSION:
1507				case RPC_EVAL_RMIR_MODEL:
1508				case RPC_EVAL_SMIR_MODEL:
1509				case RPC_EVAL_CMIR_MODEL:
1510				case RPC_EVAL_INTERMEDIATE_MODEL:
1511				case RPC_EVAL_UNIVERSAL_MODEL:
1512
1513					*p_convert_type = idl_cs_new_buffer_convert;
1514
1515					if (p_w_storage_len != NULL)
1516                        *p_w_storage_len = l_storage_len
1517						      * sizeof(wchar_t);
1518
1519					*status = rpc_s_ok;
1520
1521					if (method_p->fixed)
1522					   method_p->tags.type_handle
1523						= (rpc_ns_handle_t)*p_convert_type;
1524					break;
1525
1526				default:
1527					*status = rpc_s_ss_incompatible_codesets;
1528					break;
1529
1530				}
1531			}
1532			break;
1533
1534		case RPC_CS_EVAL_TAGS:
1535			tags_p = &bind_p->cs_eval.tagged_union.tags_key;
1536
1537			if (tags_p->type_handle != NULL)
1538			{
1539				*p_convert_type = (idl_cs_convert_t)tags_p->type_handle;
1540
1541				if (p_w_storage_len != NULL)
1542				   *p_w_storage_len = l_storage_len
1543							* sizeof(wchar_t);
1544
1545				*status = rpc_s_ok;
1546			}
1547			else
1548			{
1549				/*
1550				 * Determine the conversion type.
1551				 */
1552				*p_convert_type = idl_cs_new_buffer_convert;
1553				if (p_w_storage_len != NULL)
1554			    		*p_w_storage_len = l_storage_len * sizeof(wchar_t);
1555				*status = rpc_s_ok;
1556
1557				tags_p->type_handle =
1558					(rpc_ns_handle_t)*p_convert_type;
1559			}
1560			break;
1561
1562		default:
1563			*status = rpc_s_ss_incompatible_codesets;
1564			break;
1565		}
1566	}
1567	else	/* Server side */
1568	{
1569		*p_convert_type = idl_cs_new_buffer_convert;
1570
1571		if (p_w_storage_len != NULL)
1572		    *p_w_storage_len = l_storage_len * sizeof(wchar_t);
1573
1574		*status = rpc_s_ok;
1575	}
1576	return;
1577}
1578
1579
1580/*
1581**++
1582**  ROUTINE NAME:       cs_byte_local_size
1583**
1584**  SCOPE:              PUBLIC - declared in dce/codesets_stub.h
1585**
1586**  DESCRIPTION:
1587**
1588**  Calculate the necessary buffer size for code set converesion, based on
1589**  the information from a binding handle, tag, and on-the_wire storage size.
1590**
1591**  INPUTS:
1592**
1593**      h		Binding handle
1594**
1595**      tag		Identifies the code set that will be used on the wire.
1596**			When the caller is a client stub, this is cs_stag value.
1597**			When the caller is a server stub, this is cs_rtag value.
1598**
1599**      w_storage_len	The size, in units of byte, of the on-the_wire storage
1600**			allocated for the I-char data.
1601**
1602**  OUTPUTS:
1603**
1604**	p_convert_type	Indicate whether data conversion is necessary.
1605**			In case of  idl_cs_in_place_convert, w_storage_len
1606**			is assumed to be sufficient for the buffer size.
1607**
1608**	p_l_storage_len	NULL if fixed or varying array is being marshalled.
1609**			When conformant or conformant varying array is being
1610**			marshalled, and p_convert_type is idl_cs_new_buffer
1611**			convert, this is the storage size in units of idl_byte.
1612**
1613**      status          The status of the operation.
1614**                      Can be one of:
1615**                          rpc_s_ok
1616**                          rpc_ss_incompatible_codesets
1617**                      or a status returned from a called routine.
1618**
1619**  IMPLICIT INPUTS:    none
1620**
1621**  IMPLICIT OUTPUTS:   none
1622**
1623**  FUNCTION VALUE:     void
1624**
1625**  SIDE EFFECTS:       none
1626**
1627**--
1628*/
1629
1630PUBLIC void cs_byte_local_size
1631(
1632	rpc_binding_handle_t	h,
1633	unsigned32		tag,		/* wire encoding */
1634	unsigned32		w_storage_len,
1635	idl_cs_convert_t	*p_convert_type,
1636	unsigned32		*p_l_storage_len,
1637	error_status_t		*status
1638)
1639{
1640	char			*current_codeset;
1641	unsigned32		current_rgy_codeset;
1642	unsigned16		stag_bytes;
1643	unsigned16		client_bytes;
1644
1645	rpc_cs_method_eval_p_t	method_p;
1646	rpc_cs_tags_eval_p_t	tags_p;
1647	rpc_binding_rep_p_t 	bind_p;
1648
1649	bind_p = (rpc_binding_rep_p_t)h;
1650	if (!RPC_BINDING_IS_SERVER (bind_p))
1651	{
1652		switch (bind_p->cs_eval.key)
1653		{
1654		case RPC_CS_EVAL_METHOD:
1655			method_p = &bind_p->cs_eval.tagged_union.method_key;
1656
1657			if (method_p->tags.type_handle != NULL)
1658			{
1659				if ((idl_cs_convert_t)method_p->tags.type_handle
1660						==  idl_cs_no_convert ||
1661				    (idl_cs_convert_t)method_p->tags.type_handle
1662						==  idl_cs_in_place_convert)
1663				{
1664
1665					*p_convert_type = (idl_cs_convert_t)
1666						method_p->tags.type_handle;
1667
1668					if (p_l_storage_len != NULL)
1669				   		*p_l_storage_len = w_storage_len;
1670					*status = rpc_s_ok;
1671
1672				}
1673				else if ((idl_cs_convert_t)method_p->tags.type_handle
1674						==  idl_cs_new_buffer_convert)
1675				{
1676					*p_convert_type = (idl_cs_convert_t)
1677						method_p->tags.type_handle;
1678
1679					if (p_l_storage_len != NULL)
1680					   *p_l_storage_len = w_storage_len
1681						* method_p->tags.stag_max_bytes;
1682
1683					*status = rpc_s_ok;
1684
1685				}
1686			}
1687			else
1688			{
1689				switch (method_p->method)
1690				{
1691				case RPC_EVAL_NO_CONVERSION:
1692				case RPC_EVAL_SMIR_MODEL:
1693				case RPC_EVAL_CMIR_MODEL:
1694				case RPC_EVAL_RMIR_MODEL:
1695				case RPC_EVAL_INTERMEDIATE_MODEL:
1696				case RPC_EVAL_UNIVERSAL_MODEL:
1697
1698					if ((method_p->fixed) &&
1699					    (method_p->tags.stag_max_bytes ==
1700					    method_p->tags.client_max_bytes))
1701					{
1702					     *p_convert_type = idl_cs_in_place_convert;
1703
1704					     if (p_l_storage_len != NULL)
1705						  *p_l_storage_len = w_storage_len;
1706					}
1707					else if (method_p->tags.stag_max_bytes ==
1708						method_p->client->codesets[0].c_max_bytes)
1709					{
1710					     *p_convert_type = idl_cs_in_place_convert;
1711
1712					     if (p_l_storage_len != NULL)
1713						  *p_l_storage_len = w_storage_len;
1714					}
1715					else
1716					{
1717					    *p_convert_type = idl_cs_new_buffer_convert;
1718					    if (p_l_storage_len != NULL)
1719                            *p_l_storage_len = w_storage_len
1720						     * method_p->tags.stag_max_bytes;
1721					}
1722					*status = rpc_s_ok;
1723
1724					if (method_p->fixed)
1725						method_p->tags.type_handle =
1726						(rpc_ns_handle_t)*p_convert_type;
1727					break;
1728
1729				default:
1730					*status = rpc_s_ss_incompatible_codesets;
1731					break;
1732
1733				}
1734			}
1735			break;
1736
1737		case RPC_CS_EVAL_TAGS:
1738			tags_p = &bind_p->cs_eval.tagged_union.tags_key;
1739
1740			if (tags_p->type_handle != NULL)
1741			{
1742				if ((idl_cs_convert_t)tags_p->type_handle
1743						== idl_cs_no_convert ||
1744				(idl_cs_convert_t)tags_p->type_handle
1745						== idl_cs_in_place_convert)
1746				{
1747					*p_convert_type =
1748					     (idl_cs_convert_t)tags_p->type_handle;
1749					if (p_l_storage_len != NULL)
1750				   		*p_l_storage_len = w_storage_len;
1751					*status = rpc_s_ok;
1752
1753				}
1754				else if ((idl_cs_convert_t)tags_p->type_handle
1755						== idl_cs_new_buffer_convert)
1756				{
1757					*p_convert_type =
1758					     (idl_cs_convert_t)tags_p->type_handle;
1759					if (p_l_storage_len != NULL)
1760					   *p_l_storage_len  =
1761						w_storage_len * tags_p->stag_max_bytes;
1762					*status = rpc_s_ok;
1763				}
1764			}
1765			else
1766			{
1767				/*
1768				 * Determine the conversion type.
1769				 */
1770				if (tag == tags_p->client_tag)
1771						/* No conversion required */
1772				{
1773					*p_convert_type = idl_cs_no_convert;
1774					if (p_l_storage_len != NULL)
1775						*p_l_storage_len = w_storage_len;
1776				}
1777				else
1778				{
1779					if (tags_p->stag_max_bytes ==
1780						tags_p->client_max_bytes)
1781					{
1782						*p_convert_type
1783						     = idl_cs_in_place_convert;
1784
1785					     if (p_l_storage_len != NULL)
1786						     *p_l_storage_len = w_storage_len;
1787					}
1788					else
1789					{
1790						*p_convert_type
1791						    = idl_cs_new_buffer_convert;
1792
1793						if (p_l_storage_len != NULL)
1794                            *p_l_storage_len
1795							= w_storage_len * tags_p->stag_max_bytes;
1796					}
1797
1798				}
1799				*status = rpc_s_ok;
1800
1801				tags_p->type_handle
1802					= (rpc_ns_handle_t) *p_convert_type;
1803			}
1804			break;
1805
1806		default:
1807			*status = rpc_s_ss_incompatible_codesets;
1808			break;
1809		}
1810	}
1811	else	/* Server side */
1812	{
1813		/*
1814		 * Get the code set info from the current locale.
1815		 */
1816		current_codeset = nl_langinfo(CODESET);
1817		dce_cs_loc_to_rgy(
1818			(unsigned_char_p_t)current_codeset,
1819			&current_rgy_codeset,
1820			NULL, NULL,
1821			status);
1822
1823		if (*status != dce_cs_c_ok)
1824		{
1825			/* codeset registry error */
1826			*status = rpc_s_ok;
1827			return;
1828		}
1829
1830		/*
1831		 * Determine the conversion type.
1832		 */
1833		if (tag == current_rgy_codeset)
1834				/* No conversion required */
1835		{
1836			*p_convert_type = idl_cs_no_convert;
1837
1838			if (p_l_storage_len != NULL)
1839				*p_l_storage_len = w_storage_len;
1840
1841			*status = rpc_s_ok;
1842		}
1843		else
1844		{
1845			rpc_rgy_get_max_bytes (
1846				tag,
1847				&stag_bytes,
1848				status );
1849
1850			if (*status != rpc_s_ok)
1851				return;
1852
1853			rpc_rgy_get_max_bytes (
1854				current_rgy_codeset,
1855				&client_bytes,
1856				status );
1857
1858			if (*status != rpc_s_ok)
1859				return;
1860
1861			if (stag_bytes == client_bytes)
1862			{
1863			     *p_convert_type = idl_cs_in_place_convert;
1864
1865			     if (p_l_storage_len != NULL)
1866				     *p_l_storage_len = w_storage_len;
1867			}
1868			else
1869			{
1870			     *p_convert_type = idl_cs_new_buffer_convert;
1871
1872			     if (p_l_storage_len != NULL)
1873				    *p_l_storage_len = w_storage_len * stag_bytes;
1874			}
1875
1876			*status = rpc_s_ok;
1877		}
1878	}
1879	return;
1880}
1881
1882
1883/*
1884**++
1885**  ROUTINE NAME:       wchar_t_local_size
1886**
1887**  SCOPE:              PUBLIC - declared in dce/codesets_stub.h
1888**
1889**  DESCRIPTION:
1890**
1891**  Calculate the necessary buffer size for code set converesion, based on
1892**  the information from a binding handle, tag, and on-the_wire storage size.
1893**
1894**  INPUTS:
1895**
1896**      h		Binding handle
1897**
1898**      tag		Identifies the code set that will be used on the wire.
1899**			When the caller is a client stub, this is cs_stag value.
1900**			When the caller is a server stub, this is cs_rtag value.
1901**
1902**      w_storage_len	The size, in units of byte, of the on-the_wire storage
1903**			allocated for the I-char data.
1904**
1905**  OUTPUTS:
1906**
1907**	p_convert_type	Indicate whether data conversion is necessary.
1908**			In case of  idl_cs_in_place_convert, w_storage_len
1909**			is assumed to be sufficient for the buffer size.
1910**
1911**	p_l_storage_len	NULL if fixed or varying array is being marshalled.
1912**			When conformant or conformant varying array is being
1913**			marshalled, and p_convert_type is idl_cs_new_buffer
1914**			convert, this is the storage size in units of idl_byte.
1915**
1916**      status          The status of the operation.
1917**                      Can be one of:
1918**                          rpc_s_ok
1919**                          rpc_ss_incompatible_codesets
1920**                      or a status returned from a called routine.
1921**
1922**  IMPLICIT INPUTS:    none
1923**
1924**  IMPLICIT OUTPUTS:   none
1925**
1926**  FUNCTION VALUE:     void
1927**
1928**  SIDE EFFECTS:       none
1929**
1930**--
1931*/
1932
1933PUBLIC void wchar_t_local_size
1934(
1935	rpc_binding_handle_t	h,
1936	unsigned32		tag,			/* wire encoding */
1937	unsigned32		w_storage_len,
1938	idl_cs_convert_t	*p_convert_type,
1939	unsigned32		*p_l_storage_len,	/* wchar_t size */
1940	error_status_t		*status
1941)
1942{
1943	char			*current_codeset;
1944	unsigned32		current_rgy_codeset;
1945	unsigned16		stag_bytes;
1946	unsigned16		client_bytes;
1947
1948	rpc_cs_method_eval_p_t	method_p;
1949	rpc_cs_tags_eval_p_t	tags_p;
1950	rpc_binding_rep_p_t 	bind_p;
1951
1952	bind_p = (rpc_binding_rep_p_t)h;
1953	if (!RPC_BINDING_IS_SERVER (bind_p))
1954	{
1955		switch (bind_p->cs_eval.key)
1956		{
1957		case RPC_CS_EVAL_METHOD:
1958			method_p = &bind_p->cs_eval.tagged_union.method_key;
1959
1960			if (method_p->tags.type_handle != NULL)
1961			{
1962				*p_convert_type = (idl_cs_convert_t)
1963						method_p->tags.type_handle;
1964
1965				if (p_l_storage_len != NULL)
1966				  	*p_l_storage_len = w_storage_len
1967							/ sizeof(wchar_t);
1968
1969					*status = rpc_s_ok;
1970			}
1971			else
1972			{
1973				switch (method_p->method)
1974				{
1975				case RPC_EVAL_NO_CONVERSION:
1976				case RPC_EVAL_SMIR_MODEL:
1977				case RPC_EVAL_CMIR_MODEL:
1978				case RPC_EVAL_RMIR_MODEL:
1979				case RPC_EVAL_INTERMEDIATE_MODEL:
1980				case RPC_EVAL_UNIVERSAL_MODEL:
1981
1982					*p_convert_type = idl_cs_new_buffer_convert;
1983					if (p_l_storage_len != NULL)
1984                        *p_l_storage_len =
1985						w_storage_len / sizeof(wchar_t);
1986
1987					*status = rpc_s_ok;
1988
1989					if (method_p->fixed)
1990					    method_p->tags.type_handle =
1991						(rpc_ns_handle_t)*p_convert_type;
1992					break;
1993
1994				default:
1995					*status = rpc_s_ss_incompatible_codesets;
1996					break;
1997
1998				}
1999			}
2000			break;
2001
2002		case RPC_CS_EVAL_TAGS:
2003			tags_p = &bind_p->cs_eval.tagged_union.tags_key;
2004
2005			if (tags_p->type_handle != NULL)
2006			{
2007				*p_convert_type =
2008				     (idl_cs_convert_t)tags_p->type_handle;
2009
2010				if (p_l_storage_len != NULL)
2011			   		*p_l_storage_len = w_storage_len
2012							/ sizeof(wchar_t);
2013
2014				*status = rpc_s_ok;
2015			}
2016			else
2017			{
2018				*p_convert_type = idl_cs_new_buffer_convert;
2019
2020				if (p_l_storage_len != NULL)
2021					*p_l_storage_len = w_storage_len
2022							/ sizeof(wchar_t);
2023
2024				*status = rpc_s_ok;
2025
2026				tags_p->type_handle
2027					= (rpc_ns_handle_t) *p_convert_type;
2028			}
2029			break;
2030
2031		default:
2032			*status = rpc_s_ss_incompatible_codesets;
2033			break;
2034		}
2035	}
2036	else	/* Server side */
2037	{
2038		*p_convert_type = idl_cs_new_buffer_convert;
2039
2040		if (p_l_storage_len != NULL)
2041			*p_l_storage_len = w_storage_len / sizeof(wchar_t);
2042
2043		*status = rpc_s_ok;
2044	}
2045	return;
2046}
2047
2048
2049/*
2050**++
2051**  ROUTINE NAME:       rpc_cs_get_tags
2052**
2053**  SCOPE:              PUBLIC - declared in rpc.idl
2054**
2055**  DESCRIPTION:
2056**
2057**  Select codeset conversion tags based on the binding handle
2058**
2059**  INPUTS:
2060**
2061**      h		Binding handle
2062**
2063**      server_side	boolean input to indicate if the caller is a server stub
2064**
2065**  OUTPUTS:
2066**
2067**	p_stag		tag to indicate the sending codeset by a client
2068**			When the caller is a server stub, this is unused.
2069**
2070**	p_drtag		tag to indicate the desired received codeset.
2071**			When the caller is a server stub, this is an input
2072**			When the caller is a client stub, this is an output
2073**
2074**	p_rtag		tag to indicate the sending codeset by a server
2075**			When the caller is a client stub, this is unused.
2076**
2077**      status          The status of the operation.
2078**                      Can be one of:
2079**                          rpc_s_ok
2080**                          rpc_ss_incompatible_codesets
2081**                      or a status returned from a called routine.
2082**
2083**  IMPLICIT INPUTS:    none
2084**
2085**  IMPLICIT OUTPUTS:   none
2086**
2087**  FUNCTION VALUE:     void
2088**
2089**  SIDE EFFECTS:       none
2090**
2091**--
2092*/
2093
2094PUBLIC void rpc_cs_get_tags
2095(
2096	rpc_binding_handle_t	h,
2097	idl_boolean		server_side,
2098	unsigned32		*p_stag,
2099	unsigned32		*p_drtag,
2100	unsigned32		*p_rtag,
2101	error_status_t		*status
2102)
2103{
2104	rpc_binding_rep_p_t	bind_p;
2105	rpc_cs_method_eval_p_t	method_p;
2106	rpc_cs_tags_eval_p_t	tags_p;
2107	unsigned_char_t		*entry_name;
2108	int			i, j;
2109	rpc_codeset_mgmt_p_t	client, server;
2110	int			model_found, smir_true, cmir_true;
2111	long			i_code;
2112	int			i_max_bytes;
2113	error_status_t		temp_status;
2114
2115	if (!server_side)
2116	{
2117		bind_p = (rpc_binding_rep_p_t)h;
2118
2119		if (bind_p->extended_bind_flag == RPC_C_BH_EXTENDED_CODESETS)
2120		{
2121			/*
2122	 		 * Determine the data structure
2123	 		 */
2124			switch (bind_p->cs_eval.key)
2125			{
2126			case RPC_CS_EVAL_METHOD:
2127				method_p = &bind_p->cs_eval.tagged_union.method_key;
2128
2129				if (method_p->fixed)
2130				{
2131					*p_stag = method_p->tags.stag;
2132					*p_drtag = method_p->tags.drtag;
2133				}
2134				else
2135				{
2136					/*
2137					 * We will evaluate code set I14Y here
2138					 */
2139					 (*(method_p->cs_stub_eval_func))(p_stag, p_drtag, status);
2140					if (*status != rpc_s_ok)
2141						return;
2142
2143				        method_p->tags.stag = *p_stag;
2144				        method_p->tags.drtag = *p_drtag;
2145
2146					rpc_rgy_get_max_bytes (
2147						*p_stag,
2148						&method_p->tags.stag_max_bytes,
2149						status
2150                                        );
2151
2152					if (*status != rpc_s_ok)
2153						return;
2154
2155					/* Get client's supported code sets */
2156					rpc_rgy_get_codesets (
2157						&client,
2158						status );
2159
2160					if (*status != rpc_s_ok)
2161						return;
2162
2163				        method_p->tags.client_tag = client->codesets[0].c_set;
2164				        method_p->tags.client_max_bytes = client->codesets[0].c_max_bytes;
2165				        method_p->tags.type_handle = NULL;
2166				}
2167
2168				break;
2169
2170			case RPC_CS_EVAL_TAGS:
2171				tags_p = &bind_p->cs_eval.tagged_union.tags_key;
2172
2173				*p_stag = tags_p->stag;
2174				*p_drtag = tags_p->drtag;
2175
2176				break;
2177
2178			default:
2179				*status = rpc_s_ss_invalid_codeset_tag;
2180			}
2181
2182			*status = rpc_s_ok;
2183		}
2184		else
2185		{
2186			/* No evaluation is done so far, so we try to figure
2187			 * out if server and client are compatible
2188			 */
2189
2190			/* Get the client's supported code sets */
2191			rpc_rgy_get_codesets (
2192				&client,
2193				status );
2194
2195			if (*status != rpc_s_ok)
2196				return;
2197
2198			/* Get the name of server entry in NSI */
2199			rpc_ns_binding_inq_entry_name (
2200				h,
2201				rpc_c_ns_syntax_default,
2202				&entry_name,
2203				status );
2204
2205			if (*status != rpc_s_ok)
2206			{
2207				rpc_ns_mgmt_free_codesets(&client, &temp_status);
2208				return;
2209			}
2210
2211			/* Get the server's supported code sets from NSI */
2212			rpc_ns_mgmt_read_codesets (
2213				rpc_c_ns_syntax_default,
2214				entry_name,
2215				&server,
2216				status );
2217
2218			if (*status != rpc_s_ok)
2219			{
2220			     rpc_ns_mgmt_free_codesets(&client, &temp_status);
2221			     return;
2222			}
2223
2224			/*  Start evaluation */
2225			if (client->codesets[0].c_set == server->codesets[0].c_set)
2226			{
2227			    /* client and server are using the same code set */
2228			    *p_stag = client->codesets[0].c_set;
2229			    *p_drtag = server->codesets[0].c_set;
2230
2231			    tags_p->stag = *p_stag;
2232			    tags_p->drtag = *p_drtag;
2233			    tags_p->stag_max_bytes = client->codesets[0].c_max_bytes;
2234			    tags_p->client_tag = client->codesets[0].c_set;
2235			    tags_p->client_max_bytes = client->codesets[0].c_max_bytes;
2236			    tags_p->type_handle = NULL;
2237			}
2238			else
2239			{
2240			     /* Check character set compatibility first */
2241			     rpc_cs_char_set_compat_check (
2242				client->codesets[0].c_set,
2243				server->codesets[0].c_set,
2244				status );
2245
2246			     if (*status != rpc_s_ok)
2247			     {
2248				rpc_ns_mgmt_free_codesets(&server, &temp_status);
2249				rpc_ns_mgmt_free_codesets(&client, &temp_status);
2250				return;
2251			     }
2252
2253			     smir_true = cmir_true = model_found = 0;
2254
2255			     for (i = 1; i <= server->count; i++)
2256			     {
2257				if (model_found)
2258					break;
2259
2260				if (client->codesets[0].c_set
2261					== server->codesets[i].c_set)
2262				{
2263					smir_true = 1;
2264					model_found = 1;
2265				}
2266
2267				if (server->codesets[0].c_set
2268					== client->codesets[i].c_set)
2269				{
2270					cmir_true = 1;
2271					model_found = 1;
2272				}
2273			     }
2274
2275			     if (model_found)
2276			     {
2277				tags_p = &bind_p->cs_eval.tagged_union.tags_key;
2278
2279				if (smir_true && cmir_true)
2280				{
2281					/* RMIR model works */
2282					*p_stag = client->codesets[0].c_set;
2283					*p_drtag = server->codesets[0].c_set;
2284
2285					tags_p->stag = *p_stag;
2286					tags_p->drtag = *p_drtag;
2287					tags_p->stag_max_bytes = client->codesets[0].c_max_bytes;
2288					tags_p->client_tag = client->codesets[0].c_set;
2289					tags_p->client_max_bytes = client->codesets[0].c_max_bytes;
2290					tags_p->type_handle = NULL;
2291				}
2292				else if (smir_true)
2293				{
2294					/* SMIR model */
2295					*p_stag = client->codesets[0].c_set;
2296					*p_drtag = client->codesets[0].c_set;
2297
2298					tags_p->stag = *p_stag;
2299					tags_p->drtag = *p_drtag;
2300					tags_p->stag_max_bytes = client->codesets[0].c_max_bytes;
2301					tags_p->client_tag = client->codesets[0].c_set;
2302					tags_p->client_max_bytes = client->codesets[0].c_max_bytes;
2303					tags_p->type_handle = NULL;
2304				}
2305				else
2306				{
2307					/* CMIR model */
2308					*p_stag = server->codesets[0].c_set;
2309					*p_drtag = server->codesets[0].c_set;
2310
2311					tags_p->stag = *p_stag;
2312					tags_p->drtag = *p_drtag;
2313					tags_p->stag_max_bytes = server->codesets[0].c_max_bytes;
2314					tags_p->client_tag = client->codesets[0].c_set;
2315					tags_p->client_max_bytes = client->codesets[0].c_max_bytes;
2316					tags_p->type_handle = NULL;
2317				}
2318				*status = rpc_s_ok;
2319			     }
2320			     else
2321			     {
2322				/* Try to find the intermediate code set */
2323				tags_p->client_tag = client->codesets[0].c_set;
2324				tags_p->client_max_bytes = client->codesets[0].c_max_bytes;
2325				tags_p->type_handle = NULL;
2326
2327				for (i = 1; i <= client->count; i++)
2328				{
2329				    if (model_found)
2330					break;
2331
2332				    for (j = 1; j <= server->count; j++)
2333				    {
2334					if (client->codesets[i].c_set
2335                                                == server->codesets[j].c_set)
2336					{
2337						*p_stag = client->codesets[i].c_set;
2338						*p_drtag = client->codesets[i].c_set;
2339						tags_p->stag = *p_stag;
2340						tags_p->drtag = *p_drtag;
2341                                                tags_p->stag_max_bytes = client->codesets[i].c_max_bytes;
2342                                                model_found = 1;
2343                                                   break;
2344                                        }
2345                                    }
2346				}
2347
2348				if (!model_found)
2349				{
2350				    /* We use UNIVERSAL code set */
2351				    *p_stag = UCS2_L2;
2352				    *p_drtag = UCS2_L2;
2353				    tags_p->stag = *p_stag;
2354				    tags_p->drtag = *p_drtag;
2355				    tags_p->stag_max_bytes = client->codesets[i].c_max_bytes;
2356
2357				    rpc_rgy_get_max_bytes (
2358					UCS2_L2,
2359					&tags_p->stag_max_bytes,
2360					status
2361				    );
2362				}
2363			     }
2364			}
2365
2366			rpc_ns_mgmt_free_codesets(&server, &temp_status);
2367			rpc_ns_mgmt_free_codesets(&client, &temp_status);
2368			bind_p->extended_bind_flag = RPC_C_BH_EXTENDED_CODESETS;
2369		}
2370	}
2371	else	/* server side */
2372	{
2373		if (p_rtag != p_drtag)
2374			*p_rtag = *p_drtag;
2375
2376		*status = rpc_s_ok;
2377	}
2378	return;
2379}
2380