#include "idl_types.h"

/*
  endpoint mapper interface
  Related links:
	http://www.opengroup.org/onlinepubs/9629399/apdxo.htm : The official IDL for this pipe
	http://www.opengroup.org/onlinepubs/9629399/apdxl.htm : Details on towers
http://www.opengroup.org/onlinepubs/9629399/chap6.htm#tagcjh_11_02_03_01: binding strings

*/

import "misc.idl";

[
 uuid("e1af8308-5d1f-11c9-91a4-08002b14a0fa"), 
 version(3.0), 
 endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]",
	  "ncacn_http:[593]", "ncalrpc:[EPMAPPER]"),
 helpstring("EndPoint Mapper"),
 pointer_default(ptr)
]
interface epmapper
{

	/*
	  note that the following IDL won't work in MIDL, and in fact
	  that the full towers/floors representation of epm cannot be
	  represented in MIDL at all. I decided to represent it using
	  the extended IDL syntax in pidl to make it easier to work
	  with.
	*/

	const int EPMAPPER_STATUS_CANT_PERFORM_OP = 0x6d8;
	const int EPMAPPER_STATUS_NO_MORE_ENTRIES = 0x16c9a0d6;
	const int EPMAPPER_STATUS_NO_MEMORY = 0x16C9A012;
	const int EPMAPPER_STATUS_OK = 0;

	typedef [enum8bit] enum {
		
		/* Level 4 and higher */
		EPM_PROTOCOL_DNET_NSP		= 0x04,
		EPM_PROTOCOL_OSI_TP4  		= 0x05,
		EPM_PROTOCOL_OSI_CLNS 		= 0x06,
		EPM_PROTOCOL_TCP     		= 0x07,
		EPM_PROTOCOL_UDP     		= 0x08,
		EPM_PROTOCOL_IP      		= 0x09,
		/* These 4 are protocol identifiers, always at level 3 or lower */
		EPM_PROTOCOL_NCADG 			= 0x0a, /* Connectionless RPC */
		EPM_PROTOCOL_NCACN 			= 0x0b,
		EPM_PROTOCOL_NCALRPC 		= 0x0c, /* Local RPC */
		EPM_PROTOCOL_UUID 			= 0x0d,
		EPM_PROTOCOL_IPX  			= 0x0e,
		EPM_PROTOCOL_SMB     		= 0x0f,
		EPM_PROTOCOL_NAMED_PIPE		= 0x10,
		EPM_PROTOCOL_NETBIOS 		= 0x11,
		EPM_PROTOCOL_NETBEUI   		= 0x12,
		EPM_PROTOCOL_SPX     		= 0x13,
		EPM_PROTOCOL_NB_IPX  		= 0x14, /* NetBIOS over IPX */
		EPM_PROTOCOL_DSP 			= 0x16, /* AppleTalk Data Stream Protocol */
		EPM_PROTOCOL_DDP		    = 0x17, /* AppleTalk Data Datagram Protocol */
		EPM_PROTOCOL_APPLETALK		= 0x18, /* AppleTalk */
		EPM_PROTOCOL_VINES_SPP		= 0x1a, 
		EPM_PROTOCOL_VINES_IPC		= 0x1b, /* Inter Process Communication */
		EPM_PROTOCOL_STREETTALK		= 0x1c, /* Vines Streettalk */
		EPM_PROTOCOL_HTTP    		= 0x1f,
		EPM_PROTOCOL_UNIX_DS  		= 0x20, /* Unix domain socket */
		EPM_PROTOCOL_NULL			= 0x21
	} epm_protocol;

	typedef struct {
		/*FIXME	*/
	} epm_rhs_dnet_nsp;

	typedef struct {
		/*FIXME*/
	} epm_rhs_osi_tp4;

	typedef struct {
		/*FIXME*/
	} epm_rhs_osi_clns;
	
	typedef struct {
		uint16 port;
	} epm_rhs_udp;

	typedef struct {
		uint16 port;
	} epm_rhs_tcp;

	typedef struct {
		ipv4address ipaddr;
	} epm_rhs_ip;

	typedef struct {
		uint16 minor_version;
	} epm_rhs_ncadg;

	typedef struct {
		uint16 minor_version;
	} epm_rhs_ncacn;

	typedef struct {
		[flag(NDR_REMAINING)] DATA_BLOB unknown;
	} epm_rhs_uuid;

	typedef struct {
		/*FIXME	*/
	} epm_rhs_ipx;

	typedef struct {
		astring unc;
	} epm_rhs_smb;

	typedef struct {
		astring path;
	} epm_rhs_named_pipe;

	typedef struct {
		astring name;
	} epm_rhs_netbios;

	typedef struct {
	} epm_rhs_netbeui;

	typedef struct {
	} epm_rhs_spx;

	typedef struct {
	} epm_rhs_nb_ipx;

	typedef struct {
		uint16 port;
	} epm_rhs_http;

	typedef struct {
		astring path;
	} epm_rhs_unix_ds;

	typedef struct {
	} epm_rhs_null;

	typedef struct {
		uint16 minor_version;
	} epm_rhs_ncalrpc;

	typedef struct {
	} epm_rhs_appletalk;

	typedef struct {
	} epm_rhs_atalk_stream;

	typedef struct {
	} epm_rhs_atalk_datagram;

	typedef struct {
		uint16 port;
	} epm_rhs_vines_spp;

	typedef struct {
		uint16 port;
	} epm_rhs_vines_ipc;

	typedef struct {
		astring streettalk;
	} epm_rhs_streettalk;

	typedef [flag(NDR_BIG_ENDIAN),nodiscriminant] union {
		[case(EPM_PROTOCOL_DNET_NSP)] epm_rhs_dnet_nsp dnet_nsp;
		[case(EPM_PROTOCOL_OSI_TP4)] epm_rhs_osi_tp4 osi_tp4;
		[case(EPM_PROTOCOL_OSI_CLNS)] epm_rhs_osi_clns osi_clns;
		[case(EPM_PROTOCOL_TCP)] epm_rhs_tcp tcp;
		[case(EPM_PROTOCOL_UDP)] epm_rhs_udp udp;
		[case(EPM_PROTOCOL_IP)] epm_rhs_ip ip;
		[case(EPM_PROTOCOL_NCADG)] epm_rhs_ncadg ncadg;
		[case(EPM_PROTOCOL_NCACN)] epm_rhs_ncacn ncacn;
		[case(EPM_PROTOCOL_NCALRPC)] epm_rhs_ncalrpc ncalrpc;
		[case(EPM_PROTOCOL_UUID)] epm_rhs_uuid uuid;
		[case(EPM_PROTOCOL_IPX)] epm_rhs_ipx ipx;
		[case(EPM_PROTOCOL_SMB)] epm_rhs_smb smb;
		[case(EPM_PROTOCOL_NAMED_PIPE)] epm_rhs_named_pipe named_pipe;
		[case(EPM_PROTOCOL_NETBIOS)] epm_rhs_netbios netbios;
		[case(EPM_PROTOCOL_NETBEUI)] epm_rhs_netbeui netbeui;
		[case(EPM_PROTOCOL_SPX)] epm_rhs_spx spx;
		[case(EPM_PROTOCOL_NB_IPX)] epm_rhs_nb_ipx nb_ipx;
		[case(EPM_PROTOCOL_DSP)] epm_rhs_atalk_stream atalk_stream;
		[case(EPM_PROTOCOL_DDP)] epm_rhs_atalk_datagram atalk_datagram;
		[case(EPM_PROTOCOL_APPLETALK)] epm_rhs_appletalk appletalk;
		[case(EPM_PROTOCOL_VINES_SPP)] epm_rhs_vines_spp vines_spp;
		[case(EPM_PROTOCOL_VINES_IPC)] epm_rhs_vines_ipc vines_ipc;
		[case(EPM_PROTOCOL_STREETTALK)] epm_rhs_streettalk streettalk;
		[case(EPM_PROTOCOL_HTTP)] epm_rhs_http http;
		[case(EPM_PROTOCOL_UNIX_DS)] epm_rhs_unix_ds unix_ds;
		[case(EPM_PROTOCOL_NULL)] epm_rhs_null null;
		[default]  [flag(NDR_REMAINING)] DATA_BLOB unknown;
	} epm_rhs;

	typedef struct {
		epm_protocol protocol;
		[flag(NDR_REMAINING)] DATA_BLOB lhs_data;
	} epm_lhs;

	typedef struct {
		[subcontext(2)] epm_lhs lhs;
		[subcontext(2),switch_is(lhs.protocol)] epm_rhs rhs;
	} epm_floor;

	/* note that the NDR_NOALIGN flag is inherited by all nested
	   structures. All of the towers/floors stuff is
	   non-aligned. I wonder what sort of wicked substance these
	   guys were smoking?
	*/
	typedef [gensize,flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN)] struct {
		uint16 num_floors;
		epm_floor floors[num_floors];
	} epm_tower;

	typedef struct {
		[value(ndr_size_epm_tower(&tower, ndr->flags))] uint32  tower_length;
		[subcontext(4)] epm_tower tower;
	} epm_twr_t;

	typedef struct {
		GUID        object;
		epm_twr_t   *tower;
		/*
		 * In theory this should be:
		 *	[charset(DOS),string] uint8 annotation[64]
		 * But midl treats this as:
		 *	[charset(DOS),string] uint8 annotation[]
		 * and pidl doesn't support this yet
		 */
		[value(0)] uint32 __annotation_offset;
		[value(strlen(annotation)+1)] uint32 __annotation_length;
		[charset(DOS)] uint8 annotation[__annotation_length];
	} epm_entry_t;

	typedef struct {
		GUID                uuid;
		uint16              vers_major;
		uint16              vers_minor;
	} rpc_if_id_t;
    
	/**********************/
	/* Function 0x0       */
	error_status_t epm_Insert(
		[in]            uint32          num_ents,
		[in,size_is(num_ents)]  epm_entry_t         entries[],
		[in]            uint32          replace
		);
    
	/**********************/
	/* Function 0x1       */
	error_status_t epm_Delete(
		[in]            uint32          num_ents,
		[in, size_is(num_ents)]  epm_entry_t entries[]
		);

	typedef [v1_enum] enum {
		RPC_C_EP_ALL_ELTS		= 0x00000000,
		RPC_C_EP_MATCH_BY_IF		= 0x00000001,
		RPC_C_EP_MATCH_BY_OBJ		= 0x00000002,
		RPC_C_EP_MATCH_BY_BOTH		= 0x00000003
	} epm_InquiryType;

	typedef [v1_enum] enum {
		RPC_C_VERS_ALL			= 0x00000000,
		RPC_C_VERS_COMPATIBLE		= 0x00000001,
		RPC_C_VERS_EXACT		= 0x00000002,
		RPC_C_VERS_MAJOR_ONLY		= 0x00000003,
		RPC_C_VERS_UPTO			= 0x00000004
	} epm_VersionOption;

	/**********************/
	/* Function 0x02      */
	error_status_t epm_Lookup(
		[in]            epm_InquiryType    inquiry_type,
		[in,ptr]        GUID               *object,
		[in,ptr]        rpc_if_id_t        *interface_id,
		[in]            epm_VersionOption  vers_option,
		[in,out]        policy_handle      *entry_handle,
		[in]            uint32             max_ents,
		[out]           uint32             *num_ents,
		[out, length_is(*num_ents), size_is(max_ents)]  epm_entry_t entries[]
		);


	/**********************/
	/* Function 0x03      */

	typedef struct {
		epm_twr_t *twr;
	} epm_twr_p_t;

	[public] error_status_t epm_Map(
		[in,ptr]       GUID            *object,
		[in,ptr]       epm_twr_t       *map_tower,
		[in,out]        policy_handle   *entry_handle,
		[in]            uint32          max_towers,
		[out]           uint32          *num_towers,
		[out, length_is(*num_towers), size_is(max_towers)]  epm_twr_p_t towers[]
		);
    

	/**********************/
	/* Function 0x04      */
	error_status_t epm_LookupHandleFree(
		[in,out]        policy_handle   *entry_handle
		);
    
	/**********************/
	/* Function 0x05      */
	error_status_t epm_InqObject(
		[in]            GUID            *epm_object
		);
    

	/**********************/
	/* Function 0x06      */
	error_status_t epm_MgmtDelete(
		[in]            uint32          object_speced,
		[in,ptr]       GUID            *object,
		[in,ptr]       epm_twr_t       *tower
		);

	/**********************/
	/* Function 0x07      */
	[todo] error_status_t epm_MapAuth();
}
