[
  uuid("60a15ec5-4de8-11d7-a637-005056a20182"),
  endpoint("ncacn_np:[\\pipe\\rpcecho]", "ncacn_ip_tcp:", "ncalrpc:"),
  pointer_default(unique),
  version(1.0),
  helpstring("Simple echo pipe")
]
interface rpcecho
{
	/* Add one to an integer */
	void echo_AddOne(
		[in] uint32 in_data,
		[out] uint32 *out_data
	);
	/* Echo an array of bytes back at the caller */
	void echo_EchoData(
		[in] uint32 len,
		[in] [size_is(len)] uint8 in_data[],
		[out] [size_is(len)] uint8 out_data[]
	);
	/* Sink data to the server */
	void echo_SinkData(
		[in] uint32 len,
		[in,size_is(len)] uint8 data[]
	);
	/* Source data from server */
	void echo_SourceData(
		[in] uint32 len,
		[out,size_is(len)] uint8 data[]
	);

	/* test strings */
 	void echo_TestCall (
		[in,string,charset(UTF16)]       uint16 *s1,
		[out,string,charset(UTF16)]      uint16 **s2
 		);


	/* test some alignment issues */
	typedef struct {
		uint8 v;
	} echo_info1;

	typedef struct {
		uint16 v;
	} echo_info2;

	typedef struct {
		uint32 v;
	} echo_info3;

	typedef struct {
		hyper v;
	} echo_info4;

	typedef struct {
		uint8 v1;
		hyper v2;
	} echo_info5;

	typedef struct {
		uint8 v1;
		echo_info1 info1;
	} echo_info6;

	typedef struct {
		uint8 v1;
		echo_info4 info4;
	} echo_info7;

	typedef [switch_type(uint16)] union {
		[case(1)]  echo_info1 info1;
		[case(2)]  echo_info2 info2;
		[case(3)]  echo_info3 info3;
		[case(4)]  echo_info4 info4;
		[case(5)]  echo_info5 info5;
		[case(6)]  echo_info6 info6;
		[case(7)]  echo_info7 info7;
	} echo_Info;

	NTSTATUS echo_TestCall2 (
		     [in]                    uint16 level,
		     [out,switch_is(level)]  echo_Info *info
		);

	uint32 echo_TestSleep(
		[in] uint32 seconds
		);

	typedef enum {
		ECHO_ENUM1 = 1,
		ECHO_ENUM2 = 2
	} echo_Enum1;

	typedef [v1_enum] enum {
		ECHO_ENUM1_32 = 1,
		ECHO_ENUM2_32 = 2
	} echo_Enum1_32;

	typedef struct {
		echo_Enum1 e1;
		echo_Enum1_32 e2;
	} echo_Enum2;

	typedef [switch_type(uint16)] union {
		[case(ECHO_ENUM1)] echo_Enum1 e1;
		[case(ECHO_ENUM2)] echo_Enum2 e2;
	} echo_Enum3;

	void echo_TestEnum(
		[in,out,ref] echo_Enum1 *foo1,
		[in,out,ref] echo_Enum2 *foo2,
		[in,out,ref,switch_is(*foo1)] echo_Enum3 *foo3
		);

	typedef struct {
		uint32 x;
		[size_is(x)] uint16 surrounding[*];
	} echo_Surrounding;

	void echo_TestSurrounding(
		[in,out,ref] echo_Surrounding *data
	);

	uint16 echo_TestDoublePointer([in] uint16 ***data);
}