/*++

Copyright (c) 1996  Microsoft Corporation

Module Name:

    clusrpc.idl

Abstract:

    Interface Description for Cluster RPC interface. This contains
    two interfaces. The first is used for out-of-band cluster server
    RPC and is used for things like Join. The second is stricly for
    intra-cluster communications and runs only over the cluster
    transport.

Author:

    John Vert (jvert) 6/5/1996

--*/

cpp_quote("#ifndef _CLUSRPC_INCLUDED_")
cpp_quote("#define _CLUSRPC_INCLUDED_")


////////////////////////////////////////////////////////////////////////////
//
// Intracluster (Internal) RPC Interface Definition
//
////////////////////////////////////////////////////////////////////////////
[
uuid(e248d0b8-bf15-11cf-8c5e-08002bb49649),
version(2.0)
]
interface IntraCluster
{
import "wtypes.idl";

typedef WCHAR CLUSTER_ID[37];           // unicode representation of a GUID

//
// Interface descriptions for the FM component.
//

//
// Types
//
typedef [context_handle] void *HGROUP_ENUM_RPC;

//
// Routines and structures for dealing with Groups
//

//
// Cluster Group State
//

typedef enum _GROUP_STATE {
    GroupOnline,
    GroupOffline,
    GroupFailed,
    GroupPartialOnline
} GROUP_STATE;

//
// Group and Resource enumeration interface
//

typedef struct _GROUP_ENUM_ENTRY {
    [string] LPWSTR Id;
    DWORD State;
    DWORD StateSequence;
} GROUP_ENUM_ENTRY, *PGROUP_ENUM_ENTRY;

typedef struct _GROUP_ENUM {
    DWORD EntryCount;
    [size_is(EntryCount)] GROUP_ENUM_ENTRY Entry[*];
} GROUP_ENUM, *PGROUP_ENUM;

typedef struct _RESOURCE_ENUM_ENTRY {
    [string] LPWSTR Id;
    DWORD State;
    DWORD StateSequence;
} RESOURCE_ENUM_ENTRY, *PRESOURCE_ENUM_ENTRY;

typedef struct _RESOURCE_ENUM {
    DWORD EntryCount;
    int   ContainsQuorum;
    [size_is(EntryCount)] RESOURCE_ENUM_ENTRY Entry[*];
} RESOURCE_ENUM, *PRESOURCE_ENUM;

//
// Remotely arbitrate a group.
//
error_status_t
FmsQueryOwnedGroups(
    [ out ] PGROUP_ENUM *OwnedGroups,
    [ out ] PRESOURCE_ENUM *OwnedResources
    );

//
// Remotely bring a group online.
//

error_status_t
FmsOnlineGroupRequest(
    [ in ] LPCWSTR GroupId
    );

//
// Remotely take a group offline.
//

error_status_t
FmsOfflineGroupRequest(
    [ in ] LPCWSTR GroupId
    );

//
// Remotely move a group.
//

error_status_t
FmsMoveGroupRequest(
    [ in ] LPCWSTR GroupId,
    [ in, unique ] LPCWSTR DestinationNode
    );

//
// Remotely take a group.
//

error_status_t
FmsTakeGroupRequest(
    [ in ] LPCWSTR GroupId,
    [ in ] PRESOURCE_ENUM ResourceList
    );

//
// Remotely bring a resource online.
//

error_status_t
FmsOnlineResourceRequest(
    [ in ] LPCWSTR ResourceId
    );

//
// Remotely take a resource offline.
//

error_status_t
FmsOfflineResourceRequest(
    [ in ] LPCWSTR ResourceId
    );

//
// Remotely change node list for a resource.
//

error_status_t
FmsChangeResourceNode(
    [ in ] LPCWSTR ResourceId,
    [ in ] LPCWSTR NodeId,
    [ in ] BOOL Add
    );

//
// Remotely arbitrate a resource.
//

error_status_t
FmsArbitrateResource(
    [ in ] LPCWSTR ResourceId
    );

//
// Remotely fail a resource.
//

error_status_t
FmsFailResource(
    [ in ] LPCWSTR ResourceId
    );

//
// Remotely create a resource.
//

error_status_t
FmsCreateResource(
    [ in ] LPCWSTR GroupId,
    [ in ] LPWSTR ResourceId,
    [ in ] LPCWSTR ResourceName
    );

//
// Remotely delete a resource.
//

error_status_t
FmsDeleteResource(
    [ in ] LPCWSTR ResourceId
    );

//
// Remotely synchronize the online/offline of a resource.
//

error_status_t
FmsQuoNodeOnlineResource(
    [ in ] LPCWSTR ResourceId,
    [ in ] LPCWSTR NodeId,
    [ out ] LPDWORD State
    );

error_status_t
FmsQuoNodeOfflineResource(
    [ in ] LPCWSTR ResourceId,
    [ in ] LPCWSTR NodeId,
    [ out ] LPDWORD State
    );

error_status_t
FmsRmOnlineResource(
    [ in ] LPCWSTR ResourceId,
    [ out ] LPDWORD State
    );

error_status_t
FmsRmOfflineResource(
    [ in ] LPCWSTR ResourceId,
    [ out ] LPDWORD State
    );

//
// Remotely control a resource.
//

error_status_t
FmsResourceControl(
    [ in ] LPCWSTR ResourceId,
    [ in ] DWORD ControlCode,
    [ in, unique, size_is(InBufferSize) ] UCHAR *InBuffer,
    [ in ] DWORD InBufferSize,
    [ out, size_is(OutBufferSize), length_is(*BytesReturned) ] UCHAR *OutBuffer,
    [ in ] DWORD OutBufferSize,
    [ out ] LPDWORD BytesReturned,
    [ out ] LPDWORD Required
    );

//
// Remotely control a resource type.
//

error_status_t
FmsResourceTypeControl(
    [ in ] LPCWSTR ResourceTypeName,
    [ in ] DWORD ControlCode,
    [ in, unique, size_is(InBufferSize) ] UCHAR *InBuffer,
    [ in ] DWORD InBufferSize,
    [ out, size_is(OutBufferSize), length_is(*BytesReturned) ] UCHAR *OutBuffer,
    [ in ] DWORD OutBufferSize,
    [ out ] LPDWORD BytesReturned,
    [ out ] LPDWORD Required
    );

//
// Remotely control a group.
//

error_status_t
FmsGroupControl(
    [ in ] LPCWSTR GroupId,
    [ in ] DWORD ControlCode,
    [ in, unique, size_is(InBufferSize) ] UCHAR *InBuffer,
    [ in ] DWORD InBufferSize,
    [ out, size_is(OutBufferSize), length_is(*BytesReturned) ] UCHAR *OutBuffer,
    [ in ] DWORD OutBufferSize,
    [ out ] LPDWORD BytesReturned,
    [ out ] LPDWORD Required
    );

//
//Remotely prepare a resource to become the quorum resource(create quorum log file/take checkpoint)
//
error_status_t
FmsPrepareQuorumResChange(
    [ in ] LPCWSTR ResourceId,
    [ in ] LPCWSTR lpszQuoLogPath,
    [ in ] DWORD    dwMaxQuoLogSize
    );


//
//Remotely ask the resource to relinquish being a quorum resource or prepare a tombstone in the previous
// location of quorum log files.
//
error_status_t
FmsCompleteQuorumResChange(
    [ in ] LPCWSTR lpszResourceId,
    [ in ] LPCWSTR lpszQuoLogPath
    );

//
// Interface descriptions for the GUM component.
//
typedef UCHAR *PGUM_DATA;

error_status_t
GumQueueLockingUpdate(
    [ in ] DWORD NodeId,
    [ in ] DWORD Type,
    [ in ] DWORD Context,
    [ out ] LPDWORD Sequence,
    [ in ] DWORD BufferLength,
    [ in,size_is(BufferLength) ] PGUM_DATA Buffer
    );

#ifdef GUM_POST_SUPPORT
error_status_t
GumQueueLockingPost(
    [ in ] DWORD NodeId,
    [ in ] DWORD Type,
    [ in ] DWORD Context,
    [ out ] LPDWORD Sequence,
    [ in ] DWORD BufferLength,
    [ in,size_is(BufferLength) ] PGUM_DATA Buffer,
    [ in ] DWORD ActualBuffer
    );

error_status_t
GumDeliverPostCallback(
    [ in ] DWORD FirstNode,
    [ in ] DWORD Type,
    [ in ] DWORD Context,
    [ in ] DWORD Sequence,
    [ in ] DWORD BufferLength,
    [ in ] DWORD Buffer
    );
#endif



error_status_t
GumAttemptJoinUpdate(
    [ in ] DWORD JoiningId,
    [ in ] DWORD Type,
    [ in ] DWORD Context,
    [ in ] DWORD Sequence,
    [ in ] DWORD BufferLength,
    [ in,unique,size_is(BufferLength) ] PGUM_DATA Buffer
    );

error_status_t
GumUnlockUpdate(
    [ in ] DWORD Type,
    [ in ] DWORD Sequence
    );

error_status_t
GumUpdateNode(
    [ in ] DWORD Type,
    [ in ] DWORD Context,
    [ in ] DWORD Sequence,
    [ in ] DWORD BufferLength,
    [ in,size_is(BufferLength) ] PGUM_DATA Buffer
    );

error_status_t
GumJoinUpdateNode(
    [ in ] DWORD JoiningId,
    [ in ] DWORD Type,
    [ in ] DWORD Context,
    [ in ] DWORD Sequence,
    [ in ] DWORD BufferLength,
    [ in,unique,size_is(BufferLength) ] PGUM_DATA Buffer
    );

typedef struct _GUM_NODE_LIST {
    DWORD NodeCount;
    [size_is(NodeCount)] DWORD NodeId[*];
} GUM_NODE_LIST, *PGUM_NODE_LIST;

error_status_t
GumGetNodeSequence(
    [ in ] DWORD Type,
    [ out ] LPDWORD Sequence,
    [ out ] LPDWORD LockerNodeId,
    [ out ] PGUM_NODE_LIST *NodeList
    );


//
// Interface descriptions for the MM component.
//
error_status_t
MmRpcMsgSend(
    [ in, size_is(length) ] const UCHAR *buffer,
    [ in ] DWORD length
    );

//
// we can't import sspi.h but SECURITY_STATUS is an HRESULT
//

typedef enum _SECURITY_ROLE {
    SecurityRoleJoiningMember = 1,
    SecurityRoleClusterMember
} SECURITY_ROLE;

error_status_t
MmRpcEstablishSecurityContext(
    [ in ] DWORD NmJoinSequence,
    [ in ] DWORD EstablishingNodeId,
    [ in ] BOOL FirstTime,
    [ in ] SECURITY_ROLE RoleOfClient,
    [ in, size_is(ServerContextLength) ] const UCHAR *ServerContext,
    [ in ] DWORD ServerContextLength,
    [ out, size_is(*ClientContextLength) ] UCHAR *ClientContext,
    [ in, out ] DWORD * ClientContextLength,
    [ out ] HRESULT * ServerStatus
    );

error_status_t
MmRpcDeleteSecurityContext(
    [ in ] DWORD NodeId
    );

error_status_t
MmRpcBanishNode(
    [ in ] DWORD NodeId
    );

error_status_t
NmRpcCreateJoinerBinding(
    [in] DWORD           JoinSequence,
    [in, string] LPWSTR  JoinerNodeId,
    [in, string] LPWSTR  JoinerInterfaceId
    );

error_status_t
NmRpcDeliverJoinMessage(
    [ in, size_is(MessageLength) ] UCHAR *Message,
    [ in ] DWORD MessageLength
    );


//
// Interface descriptions for the Checkpoint Manager (CP)
//
typedef pipe byte BYTE_PIPE;

error_status_t
CpDepositCheckpoint(
    [ in ] const CLUSTER_ID ResourceId,
    [ in ] DWORD dwCheckpointId,
    [ in ] BYTE_PIPE CheckpointData
    );

error_status_t
CpRetrieveCheckpoint(
    [ in ] const CLUSTER_ID ResourceId,
    [ in ] DWORD dwCheckpointId,
    [ out ] BYTE_PIPE CheckpointData
    );

//
// Interface descriptions for the ClusterEventlog Manager (Evtlog)
//
error_status_t
EvPropEvents(
    [ in ] DWORD dwEventInfoSize,
    [in , size_is(dwEventInfoSize)] UCHAR *pPackedEventInfo
    );


//
// Interface description for the Checkpoint managaer
//
error_status_t
CpDeleteCheckpoint(
    [in] const CLUSTER_ID ResourceId,
    [in] DWORD  dwCheckpointId,
    [in, unique] LPCWSTR    lpszQuorumPath
    );

//
// New structures and procedures added for version 2.0 (NT 5.0)
// that are understood by NT4 SP4.
//

//
// Global Update Manager
//
error_status_t
GumAttemptLockingUpdate(
    [ in ] DWORD NodeId,
    [ in ] DWORD Type,
    [ in ] DWORD Context,
    [ in ] DWORD Sequence,
    [ in ] DWORD BufferLength,
    [ in,size_is(BufferLength) ] PGUM_DATA Buffer
    );

error_status_t
GumCollectVoteFromNode(
    [ in ] DWORD   UpdateType,
    [ in ] DWORD   dwContext,
    [ in ] DWORD   dwInputBufLength,
    [ in, size_is(dwInputBufLength) ] UCHAR  *pInputBuf,
    [ in ] DWORD   dwVoteLength,
    [ out, size_is(dwVoteLength) ] UCHAR  *pVoteBuf
    );

//
// Node Manager
//
typedef UCHAR  NM_STATE_ENTRY, *PNM_STATE_ENTRY;

typedef struct _NM_CONNECTIVITY_VECTOR {
    DWORD                                   EntryCount;
    [ size_is(EntryCount) ] NM_STATE_ENTRY  Data[*];
} NM_CONNECTIVITY_VECTOR, *PNM_CONNECTIVITY_VECTOR;

typedef struct _NM_ADDRESS_ENUM {
    DWORD                              AddressSize;
    DWORD                              AddressCount;
    [size_is(AddressCount)] ULONGLONG  AddressList[*];
} NM_ADDRESS_ENUM, *PNM_ADDRESS_ENUM;

error_status_t
NmRpcReportInterfaceConnectivity(
    [ in, string ] LPWSTR              ReportingInterfaceId,
    [ in ] PNM_CONNECTIVITY_VECTOR     ConnectivityVector
    );

error_status_t
NmRpcGetInterfaceOnlineAddressEnum(
    [ in, string ] LPWSTR              InterfaceId,
    [ out ]        PNM_ADDRESS_ENUM *  InterfaceAddressEnum
    );

error_status_t
NmRpcGetInterfacePingAddressEnum(
    [ in, string ] LPWSTR              InterfaceId,
    [ in ]         PNM_ADDRESS_ENUM    OnlineAddressEnum,
    [ out ]        PNM_ADDRESS_ENUM *  PingAddressEnum
    );

//
// This call returns void rather than error_status_t because of a 
// bug in the MIDL compiler in an early beta of W2K. Making the 
// status the last argument results in the same format on the wire,
// which will enable us to change the definition later and still 
// interoperate. The call works in its current format, so there
// is little point in changing it.
//
void
NmRpcDoInterfacePing(
    [ in ]  LPWSTR             InterfaceId,
    [ in ]  PNM_ADDRESS_ENUM   PingAddressEnum,
    [ out ] BOOLEAN *          PingSucceeded,
    [ out ] error_status_t *   CallStatus
    );

//
//  Remotely request the owner of the quorum resource to make a backup of the
//  quorum log file and the checkpoint file to the supplied directory path
//
error_status_t
FmsBackupClusterDatabase(
    [ in ] LPCWSTR lpszResourceId,
    [ in ] LPCWSTR lpszPathName
    );


//
// Remotely change the group for a resource
//
error_status_t
FmsChangeResourceGroup(
    [ in ] LPCWSTR ResourceId,
    [ in ] LPCWSTR GroupId
    );

//
//  Remotely request the owner of the node to handle the delete group request.
//
error_status_t
FmsDeleteGroupRequest(
    [ in ] LPCWSTR GroupId
    );

//
// Interface descriptions for the Crypto Checkpoint Management (CP)
//
error_status_t
CpDepositCryptoCheckpoint(
    [ in ] const CLUSTER_ID ResourceId,
    [ in ] DWORD dwCheckpointId,
    [ in ] BYTE_PIPE CheckpointData
    );

error_status_t
CpRetrieveCryptoCheckpoint(
    [ in ] const CLUSTER_ID ResourceId,
    [ in ] DWORD dwCheckpointId,
    [ out ] BYTE_PIPE CheckpointData
    );

error_status_t
CpDeleteCryptoCheckpoint(
    [in] const CLUSTER_ID ResourceId,
    [in] DWORD  dwCheckpointId,
    [in, unique] LPCWSTR    lpszQuorumPath
    );

//
// Remotely add a resource dependency
//
error_status_t
FmsAddResourceDependency(
    [ in ] LPCWSTR pszResourceId,
    [ in ] LPCWSTR pszDependsOnId
    );

//
// Remotely remove a resource dependency
//
error_status_t
FmsRemoveResourceDependency(
    [ in ] LPCWSTR pszResourceId,
    [ in ] LPCWSTR pszDependsOnId
    );

//
// New structures and procedures added for version 2.0 (NT 5.0)
// that are not understood by NT4 SP4.
//
error_status_t
NmRpcAddNode(
    [ in ] LPCWSTR  NewNodeName,
    [ in ] DWORD    NewNodeHighestVersion,
    [ in ] DWORD    NewNodeLowestVersion,
    [ in ] DWORD    NewNodeProductSuite
    );

error_status_t
FmsCreateResource2(
    [ in ] LPCWSTR GroupId,
    [ in ] LPWSTR ResourceId,
    [ in ] LPCWSTR ResourceName,
    [ in ] LPCWSTR ResourceType,
    [ in ] DWORD dwFlags
    );


} // IntraCluster interface


////////////////////////////////////////////////////////////////////////////
//
// ExtroCluster (Join) RPC Interface Definition
//
////////////////////////////////////////////////////////////////////////////
[
uuid(ffe561b8-bf15-11cf-8c5e-08002bb49649),
version(2.0)
]
interface ExtroCluster
{
import "wtypes.idl";

//
// Constants
//
const unsigned long CS_MAX_NODE_NAME_LENGTH = 15; // MAX_COMPUTERNAME_LENGTH
const unsigned long CS_MAX_NODE_ID_LENGTH = 5;    // enough for 99,999 nodes
const unsigned long CS_NETWORK_ID_LENGTH = 36 ;   // size of a GUID.
const unsigned long CS_NETINTERFACE_ID_LENGTH = 36 ;   // size of a GUID.


//
// Node Configuration Information
//
typedef struct _NM_NODE_INFO {
    [string] WCHAR     NodeId[CS_MAX_NODE_ID_LENGTH + 1];
    [string] WCHAR     NodeName[CS_MAX_NODE_NAME_LENGTH + 1];
    DWORD              State;
} NM_NODE_INFO, *PNM_NODE_INFO;

typedef struct _NM_NODE_ENUM {
    DWORD                                 NodeCount;
    [ size_is(NodeCount) ] NM_NODE_INFO   NodeList[*];
} NM_NODE_ENUM, *PNM_NODE_ENUM;

//
// Network Configuration Information.
//
typedef struct _NM_INTERFACE_INFO {
    [string] LPWSTR    Id;
    [string] LPWSTR    Name;
    [string] LPWSTR    Description;
    [string] LPWSTR    NodeId;
    [string] LPWSTR    NetworkId;
    [string] LPWSTR    Adapter;
    [string] LPWSTR    Address;
    [string] LPWSTR    ClusnetEndpoint;
    DWORD              State;
    BOOLEAN            Ignore;
} NM_INTERFACE_INFO, *PNM_INTERFACE_INFO;

typedef struct _NM_INTERFACE_ENUM {
    DWORD                                          InterfaceCount;
    [ size_is(InterfaceCount) ] NM_INTERFACE_INFO  InterfaceList[*];
} NM_INTERFACE_ENUM, *PNM_INTERFACE_ENUM;

typedef struct _NM_NETWORK_INFO {
    [string] LPWSTR    Id;
    [string] LPWSTR    Name;
    [string] LPWSTR    Description;
    DWORD              Role;
    DWORD              Priority;
    [string] LPWSTR    Transport;
    [string] LPWSTR    Address;
    [string] LPWSTR    AddressMask;
    BOOLEAN            Ignore;
} NM_NETWORK_INFO, *PNM_NETWORK_INFO;

typedef struct _NM_NETWORK_ENUM {
    DWORD                                      NetworkCount;
    [ size_is(NetworkCount) ] NM_NETWORK_INFO  NetworkList[*];
} NM_NETWORK_ENUM, *PNM_NETWORK_ENUM;


//
// Routines
//
error_status_t
NmRpcEnumNodeDefinitions(
    [ in ]         DWORD            JoinSequence,
    [ in, string ] LPWSTR           JoinerNodeId,
    [ out ]        PNM_NODE_ENUM *  NodeEnum
    );

error_status_t
NmRpcEnumNetworkDefinitions(
    [ in ]         DWORD               JoinSequence,
    [ in, string ] LPWSTR              JoinerNodeId,
    [ out ]        PNM_NETWORK_ENUM *  NetworkEnum
    );

error_status_t
NmRpcEnumInterfaceDefinitions(
    [ in ]         DWORD                 JoinSequence,
    [ in, string ] LPWSTR                JoinerNodeId,
    [ out ]        PNM_INTERFACE_ENUM *  InterfaceEnum
    );

error_status_t
NmRpcCreateNetwork(
    [ in ]         DWORD                JoinSequence,
    [ in, string ] LPWSTR               JoinerNodeId,
    [ in ]         PNM_NETWORK_INFO     NetworkInfo,
    [ in ]         PNM_INTERFACE_INFO   InterfaceInfo
    );

error_status_t
NmRpcCreateInterface(
    [ in ]         DWORD               JoinSequence,
    [ in, string ] LPWSTR              JoinerNodeId,
    [ in ]         PNM_INTERFACE_INFO  InterfaceInfo
    );

error_status_t
NmRpcSetInterfaceInfo(
    [ in ]         DWORD               JoinSequence,
    [ in, string ] LPWSTR              JoinerNodeId,
    [ in ]         PNM_INTERFACE_INFO  InterfaceInfo
    );

error_status_t
NmRpcDeleteInterface(
    [ in ]         DWORD      JoinSequence,
    [ in, string ] LPWSTR     JoinerNodeId,
    [ in, string ] LPWSTR     InterfaceId,
    [ out ]        BOOLEAN *  NetworkDeleted
    );

error_status_t
NmRpcJoinBegin(
    [in, string ]   LPWSTR    JoinerNodeId,
    [in, string ]   LPWSTR    JoinerNodeName,
    [ out ]         LPDWORD   SponsorNodeId,
    [ out ]         LPDWORD   JoinSequenceNumber,
    [ out, string ] LPWSTR *  ClusnetEndpoint
    );

error_status_t
NmRpcCreateBinding(
    [ in ]         DWORD   JoinSequence,
    [ in, string ] LPWSTR  JoinerNodeId,
    [ in, string ] LPWSTR  JoinerInterfaceId,
    [ in, string ] LPWSTR  MemberNodeId
    );

error_status_t
NmRpcPetitionForMembership(
    [ in ]         DWORD    JoinSequence,
    [ in, string ] LPCWSTR  JoinerNodeId
    );

error_status_t
JoinAddNode(
    [ in, string ] LPCWSTR lpszNodeId
    );

error_status_t
DmSyncDatabase(
    [ out ]    BYTE_PIPE reg_data
    );

error_status_t
TestRPCSecurity(
    );

//
// New structures added for version 2.0 (NT 5.0) that are understood
// by NT4 SP4.
//

//
// Node Configuration Information Structure
//
typedef struct _NM_NODE_INFO2{
    [string] WCHAR     NodeId[CS_MAX_NODE_ID_LENGTH + 1];
    [string] WCHAR     NodeName[CS_MAX_NODE_NAME_LENGTH + 1];
    DWORD              State;
    //
    // New fields in Version 2.0
    //
    DWORD              NodeHighestVersion;
    DWORD              NodeLowestVersion;
} NM_NODE_INFO2, *PNM_NODE_INFO2;

typedef struct _NM_NODE_ENUM2{
    DWORD                                 NodeCount;
    [ size_is(NodeCount) ] NM_NODE_INFO2  NodeList[*];
} NM_NODE_ENUM2, *PNM_NODE_ENUM2;

//
// Network Interface Configuration Information Structure
//
// Extension of NM_INTERFACE_INFO structure. Extended fields
// are appended to the original structure.
//
typedef struct _NM_INTERFACE_INFO2 {
    [string] LPWSTR    Id;
    [string] LPWSTR    Name;
    [string] LPWSTR    Description;
    [string] LPWSTR    NodeId;
    [string] LPWSTR    NetworkId;
    [string] LPWSTR    AdapterName;  // Field renamed, but location unchanged
    [string] LPWSTR    Address;
    [string] LPWSTR    ClusnetEndpoint;
    DWORD              State;
    BOOLEAN            Ignore;
    //
    // New fields in Version 2.0
    //
    [string] LPWSTR    AdapterId;
    DWORD              NetIndex;
} NM_INTERFACE_INFO2, *PNM_INTERFACE_INFO2;

typedef struct _NM_INTERFACE_ENUM2 {
    DWORD                                           InterfaceCount;
    [ size_is(InterfaceCount) ] NM_INTERFACE_INFO2  InterfaceList[*];
} NM_INTERFACE_ENUM2, *PNM_INTERFACE_ENUM2;

cpp_quote("#define NmInvalidInterfaceNetIndex  0xFFFFFFFF")

//
// Network Interface State Information Structure
//
typedef struct _NM_INTERFACE_STATE_INFO {
    [string] LPWSTR   Id;
    DWORD             State;
} NM_INTERFACE_STATE_INFO, *PNM_INTERFACE_STATE_INFO;

typedef struct _NM_INTERFACE_STATE_ENUM {
    DWORD                                                InterfaceCount;
    [ size_is(InterfaceCount) ] NM_INTERFACE_STATE_INFO  InterfaceList[*];
} NM_INTERFACE_STATE_ENUM, *PNM_INTERFACE_STATE_ENUM;

typedef struct _NM_NETWORK_STATE_INFO {
    [string] LPWSTR   Id;
    DWORD             State;
} NM_NETWORK_STATE_INFO, *PNM_NETWORK_STATE_INFO;

typedef struct _NM_NETWORK_STATE_ENUM {
    DWORD                                            NetworkCount;
    [ size_is(NetworkCount) ] NM_NETWORK_STATE_INFO  NetworkList[*];
} NM_NETWORK_STATE_ENUM, *PNM_NETWORK_STATE_ENUM;

//
// New routines added for version 2.0 (NT 5.0) that are understood
// by NT4 SP4.
//
error_status_t
NmRpcJoinBegin2(
    [in, string ]   LPWSTR    JoinerNodeId,
    [in, string ]   LPWSTR    JoinerNodeName,
    [in ]           DWORD     JoinerHighestVersion,
    [in ]           DWORD     JoinerLowestVersion,
    [ out ]         LPDWORD   SponsorNodeId,
    [ out ]         LPDWORD   JoinSequenceNumber,
    [ out, string ] LPWSTR *  ClusnetEndpoint
    );

error_status_t
JoinAddNode2(
    [ in, string ]  LPCWSTR lpszNodeId,
    [ in ]          DWORD   dwNodeHighestVersion,
    [ in ]          DWORD   dwNodeLowestVersion
    );

error_status_t
NmRpcEnumNodeDefinitions2(
    [ in ]         DWORD             JoinSequence,
    [ in, string ] LPWSTR            JoinerNodeId,
    [ out ]        PNM_NODE_ENUM2 *  NodeEnum2
    );

error_status_t
NmRpcEnumInterfaceDefinitions2(
    [ in ]         DWORD                  JoinSequence,
    [ in, string ] LPWSTR                 JoinerNodeId,
    [ out ]        PNM_INTERFACE_ENUM2 *  InterfaceEnum2
    );

error_status_t
NmRpcCreateNetwork2(
    [ in ]         DWORD                 JoinSequence,
    [ in, string ] LPWSTR                JoinerNodeId,
    [ in ]         PNM_NETWORK_INFO      NetworkInfo,
    [ in ]         PNM_INTERFACE_INFO2   InterfaceInfo2
    );

error_status_t
NmRpcCreateInterface2(
    [ in ]         DWORD                JoinSequence,
    [ in, string ] LPWSTR               JoinerNodeId,
    [ in ]         PNM_INTERFACE_INFO2  InterfaceInfo2
    );

error_status_t
NmRpcSetInterfaceInfo2(
    [ in ]         DWORD                JoinSequence,
    [ in, string ] LPWSTR               JoinerNodeId,
    [ in ]         PNM_INTERFACE_INFO2  InterfaceInfo2
    );

error_status_t
NmRpcSetNetworkName(
    [ in ]         DWORD               JoinSequence,
    [ in, string ] LPWSTR              JoinerNodeId,
    [ in ]         PNM_NETWORK_INFO    NetworkInfo
    );

error_status_t
NmRpcReportJoinerInterfaceConnectivity(
    [ in ]         DWORD                    JoinSequence,
    [ in, string ] LPWSTR                   JoinerNodeId,
    [ in, string ] LPWSTR                   ReportingInterfaceId,
    [ in ]         PNM_CONNECTIVITY_VECTOR  ConnectivityVector
    );

error_status_t
NmRpcEnumNetworkAndInterfaceStates(
    [ in ]         DWORD                       JoinSequence,
    [ in, string ] LPWSTR                      JoinerNodeId,
    [ out ]        PNM_NETWORK_STATE_ENUM *    NetworkStateEnum,
    [ out ]        PNM_INTERFACE_STATE_ENUM *  InterfaceStateEnum
    );

error_status_t
NmRpcGetLeaderNodeId(
    [ in ]         DWORD    JoinSequence,
    [ in, string ] LPWSTR   JoinerNodeId,
    [ out ]        LPDWORD  LeaderNodeId
    );

//
// New structures and procedures added for version 2.0 (NT 5.0)
// that are not understood by NT4 SP4.
//
error_status_t
JoinAddNode3(
    [ in, string ]  LPCWSTR lpszNodeId,
    [ in ]          DWORD   dwNodeHighestVersion,
    [ in ]          DWORD   dwNodeLowestVersion,
    [ in ]          DWORD   dwNodeProductSuite
    );

//
// New structures and procedures added for version 2.1 (NT 5.1)
// that are not understood by NT 5.0 or earlier
//
error_status_t
NmRpcJoinBegin3(
    [in, string ]   LPWSTR    JoinerClusterInstanceId,
    [in, string ]   LPWSTR    JoinerNodeId,
    [in, string ]   LPWSTR    JoinerNodeName,
    [in ]           DWORD     JoinerHighestVersion,
    [in ]           DWORD     JoinerLowestVersion,
    [in ]           DWORD     JoinerMajorVersion,
    [in ]           DWORD     JoinerMinorVersion,
    [in, string ]   LPWSTR    JoinerCsdVersion,
    [in ]           DWORD     JoinerProductSuite,
    [ out ]         LPDWORD   SponsorNodeId,
    [ out ]         LPDWORD   JoinSequenceNumber,
    [ out, string ] LPWSTR *  ClusnetEndpoint
    );

} // ExtroCluster interface


////////////////////////////////////////////////////////////////////////////
//
// Join Version RPC Interface Definition
//
// Don't ever change this interface unless you really, really,
// really know what you're doing.
//
////////////////////////////////////////////////////////////////////////////
[
uuid(6e17aaa0-1a47-11d1-98bd-0000f875292e),
version(2.0)
]
interface JoinVersion
{
import "wtypes.idl";

error_status_t
CsRpcGetJoinVersionData(
    [ in  ] DWORD     JoiningNodeId,
    [ in  ] DWORD     JoinerHighestVersion,
    [ in  ] DWORD     JoinerLowestVersion,
    [ out ] LPDWORD   SponsorNodeId,
    [ out ] LPDWORD   ClusterHighestVersion,
    [ out ] LPDWORD   ClusterLowestVersion,
    [ out ] LPDWORD   JoinStatus
    );

} // JoinVersion interface


cpp_quote("#endif //_CLUSRPC_INCLUDED_")
