[ofw] WinVerbs and RDMA CM support

Sean Hefty sean.hefty at intel.com
Mon Feb 4 16:22:52 PST 2008


The following include file provides a rough framework for adding rdma_cm
support to a Windows RDMA software stack.  General APIs are defined for
a 'WinVerbs' interface capable of supporting NDI, but one that allows
all applications to gain the benefits of using overlapped I/O.

I'd like to get feedback on this approach, in particular the areas around
rdma_cm support (Endpoints, ConnectEndpoints, DatagramEndpoints, Listens),
and specifically around supporting librdmacm and NDI interfaces above these
routines.  The other routines are mostly either wrappers around the existing
routines, or changes required for NDI support.

I would like to discuss this approach with respect to supporting NDI in a
generic fashion as part of a Windows OFA software release version 2.0,
with potential target dates between June - August of this year.  The hope
is that the hardware specific drivers, for both userspace and the kernel,
_could_ be relatively unchanged, unless optimized.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>

---

/*
 * Copyright (c) 1996-2008 Intel Corporation. All rights reserved. 
 *
 * This software is available to you under the OpenIB.org BSD license
 * below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#pragma once

#ifndef _WINVERBS_H_
#define _WINVERBS_H_

#include <winsock2.h>
#include <unknwn.h>
#include "wvstatus.h"
#include "ib_al.h"

typedef ib_gid_t WV_GID;

typedef ib_ca_attr_t WV_DEVICE_ATTRIBUTES;

typedef struct _WV_ADDRESS
{
	SOCKET_ADDRESS		Address;
	UINT64			DeviceGuid;
	UINT16			PKey;
	UINT8			PortNumber;

}	WV_ADDRESS;

typedef struct _WV_ADDRESS_LIST
{
	INT			Count;
	WV_ADDRESS		Address[0];

}	WV_ADDRESS_LIST;

typedef enum _WV_DEVICE_EVENT_TYPE
{
	WV_DEVICE_ERROR,
	WV_DEVICE_PORT_ACTIVE,
	WV_DEVICE_PORT_DOWN

}	WV_DEVICE_EVENT_TYPE;

typedef struct _WV_DEVICE_EVENT
{
	HRESULT			Status;
	WV_DEVICE_EVENT_TYPE	Type;
	UINT8			PortNumber;

}	WV_DEVICE_EVENT;

typedef enum _WV_CQ_NOTIFY_FLAGS
{
	WV_CQ_SOLICITED		= 1 << 0,
	WV_CQ_NEXT_COMP		= 1 << 1,

} WV_CQ_NOTIFY_FLAGS;

typedef ib_wc_t WV_COMPLETION;

DECLARE_HANDLE(WV_MR_HANDLE);
typedef ib_local_ds_t WV_SGE;
typedef ib_recv_wr_t WV_RECEIVE_REQUEST; // TODO: update to replace handles
typedef ib_send_wr_t WV_SEND_REQUEST;	 // TODO: update to replace handles
typedef ib_grh_t WV_GRH;

typedef struct _WV_ADDRESS_VECTOR
{
	WV_GRH			Grh;
	BOOL			GrhValid;
	UINT16			DLid;			// Network byte order
	UINT8			ServiceLevel;
	UINT8			SourcePathBits;
	UINT8			StaticRate;
	UINT8			PortNumber;

}	WV_ADDRESS_VECTOR;

typedef ib_srq_attr_t WV_SRQ_ATTRIBUTES;

typedef ib_qp_type_t WV_QP_TYPE;
typedef ib_qp_state_t WV_QP_STATE;
typedef ib_apm_state_t WV_APM_STATE;

typedef struct _WV_QP_CREATE
{
	IWVCompletionQueue*	pSendCq;
	IWVCompletionQueue*	pReceiveCq;
	IWVSharedReceiveQueue*	pSharedReceiveQueue;

	SIZE_T			SendDepth;
	SIZE_T			SendSge;
	SIZE_T			ReceiveDepth;
	SIZE_T			ReceiveSge;

	WV_QP_TYPE		QpType;
	BOOL			SignalSends;

}	WV_QP_CREATE;

typedef struct _WV_QP_ATTRIBUTES
{
	IWVProtectionDomain*	pPd;
	IWVCompletionQueue*	pSendCq;
	IWVCompletionQueue*	pReceiveCq;
	IWVSharedReceiveQueue*	pSharedReceiveQueue;

	SIZE_T			SendDepth;
	SIZE_T			SendSge;
	SIZE_T			ReceiveDepth;
	SIZE_T			ReceiveSge;
	SIZE_T			MaxInlineSend;
	SIZE_T			InitiatorDepth;
	SIZE_T			ResponderResources;

	WV_QP_TYPE		QpType;
	WV_QP_STATE		CurrentQpState;
	WV_QP_STATE		QpState;
	WV_APM_STATE		ApmState;
	UINT32			QpNumber;		// Network byte order
	UINT32			DestinationQpNumber;	// Network byte order
	UINT32			QKey;			// Network byte order
	UINT32			SendPsn;		// Network byte order
	UINT32			ReceivePsn;		// Network byte order

	WV_ADDRESS_VECTOR	PrimaryAddressVector;
	WV_ADDRESS_VECTOR	AlternateAddressVector;
	BOOL			SignalSends;
	DWORD			AccessFlags;
	UINT16			PkeyIndex;

	UINT8			PathMtu;
	UINT8			LocalAckTimeout;
	UINT8			SequenceErrorRetryCount;
	UINT8			RnrRetryCount;

}	WV_QP_ATTRIBUTES;

typedef enum _WV_QP_EVENT_TYPE
{
	WV_QP_ERROR,
	WV_QP_MODIFY,
	WV_QP_COMMUNICATION_ESTABLISH,
	WV_QP_PATH_MIGRATION,
	WV_QP_SEND_QUEUE_DRAINED,
	WV_QP_LAST_SRQ_REQUEST

}	WV_QP_EVENT_TYPE;

typedef struct _WV_QP_EVENT
{
	HRESULT			Status;
	WV_QP_EVENT_TYPE	Type;

}	WV_QP_EVENT;

typedef enum _WV_CM_EVENT_TYPE
{
	WV_CM_EVENT_ADDR_RESOLVED,
	WV_CM_EVENT_ADDR_ERROR,
	WV_CM_EVENT_ROUTE_RESOLVED,
	WV_CM_EVENT_ROUTE_ERROR,
	WV_CM_EVENT_CONNECT_REQUEST,
	WV_CM_EVENT_LOOKUP_REQUEST = WV_CM_EVENT_CONNECT_REQUEST,
	WV_CM_EVENT_CONNECT_RESPONSE,
	WV_CM_EVENT_CONNECT_ERROR,
	WV_CM_EVENT_UNREACHABLE,
	WV_CM_EVENT_REJECTED,
	WV_CM_EVENT_ESTABLISHED,
	WV_CM_EVENT_DISCONNECTED,
	WV_CM_EVENT_DEVICE_REMOVAL,
	WV_CM_EVENT_MULTICAST_JOIN,
	WV_CM_EVENT_MULTICAST_ERROR

}	WV_CM_EVENT_TYPE;

#define WV_CM_UDP_QKEY 0x01234567

typedef struct _WV_CONNECT_PARAM
{
	const VOID*		pPrivateData;
	SIZE_T			PrivateDataLength;
	SIZE_T			ResponderResources;
	SIZE_T			InitiatorDepth;
	UINT8			RetryCount;		// Ignored when accepting
	UINT8			RnrRetryCount;

}	WV_CONNECT_PARAM;

typedef struct _WV_CONNECT_EVENT
{
	WV_CM_EVENT_TYPE	Event;
	HRESULT			Status;
	WV_CONNECT_PARAM	Connect;

}	WV_CONNECT_EVENT;

typedef struct _WV_CONNECT_ATTRIBUTES
{
	SOCKET_ADDRESS		LocalAddress;
	SOCKET_ADDRESS		PeerAddress;
	WV_CONNECT_EVENT	LastEvent;

}	WV_CONNECT_ATTRIBUTES;

typedef struct _WV_DATAGRAM_PARAM
{
	const VOID*		pPrivateData;
	SIZE_T			PrivateDataLength;
	WV_ADDRESS_VECTOR	AddressVector;
	UINT32			QpNumber;
	UINT32			QKey;

}	WV_DATAGRAM_PARAM;


typedef struct _WV_DATAGRAM_EVENT
{
	WV_CM_EVENT_TYPE	Event;
	HRESULT			Status;
	WV_DATAGRAM_PARAM	Datagram;

}	WV_DATAGRAM_EVENT;


typedef struct _WV_DATAGRAM_ATTRIBUTES
{
	SOCKET_ADDRESS		LocalAddress;
	SOCKET_ADDRESS		PeerAddress;
	WV_DATAGRAM_EVENT	LastEvent;

}	WV_DATAGRAM_ATTRIBUTES;


#undef INTERFACE
#define INTERFACE IWVOverlapped
DEFINE_GUID(IID_IWVOverlapped, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVOverlapped, IUnknown)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;
};


#undef INTERFACE
#define INTERFACE IWVCompletionQueue
DEFINE_GUID(IID_IWVCompletionQueue, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVCompletionQueue, IWVOverlapped)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    __override STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    __override STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;

    // IWVCompletionQueue methods
};
HRESULT IWVCompletionQueue::Resize(__inout SIZE_T *pEntries);
HRESULT IWVCompletionQueue::Peek(__out SIZE_T *pCompletedEntries);
HRESULT IWVCompletionQueue::Notify(__in WV_CQ_NOTIFY_FLAGS Flags,
				   __in OVERLAPPED* pOverlapped);
HRESULT IWVCompletionQueue::BatchNotify(__in SIZE_T CompletedEntries,
					__in OVERLAPPED* pOverlapped);
SIZE_T IWVCompletionQueue::Poll(__inout WV_COMPLETION* pCompletions[],
				__in SIZE_T Entries);


#undef INTERFACE
#define INTERFACE IWVMemoryWindow
DEFINE_GUID(IID_IWVMemoryWindow, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVMemoryWindow, IUnknown)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;
};


#undef INTERFACE
#define INTERFACE IWVAddressHandle
DEFINE_GUID(IID_IWVAddressHandle, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVAddressHandle, IUnknown)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;
};


#undef INTERFACE
#define INTERFACE IWVSharedReceiveQueue
DEFINE_GUID(IID_IWVSharedReceiveQueue, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVSharedReceiveQueue, IWVOverlapped)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    __override STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    __override STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;

    // IWVSharedReceiveQueue methods
};
HRESULT IWVSharedReceiveQueue::Modify(__in WV_SRQ_ATTRIBUTES* pAttributes,
				      __in DWORD Mask);
HRESULT IWVSharedReceiveQueue::PostReceive(__in WV_RECEIVE_REQUEST* pRequest,
					   __out_opt WV_RECEIVE_REQUEST** ppFailedRequest);
// Signaled on limit reached event
HRESULT IWVSharedReceiveQueue::Notify(__in OVERLAPPED* pOverlapped);


#undef INTERFACE
#define INTERFACE IWVQueuePair
DEFINE_GUID(IID_IWVQueuePair, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVQueuePair, IWVOverlapped)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    __override STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    __override STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;

    // IWVQueuePair methods
};
HRESULT IWVQueuePair::Query(__out WV_QP_ATTRIBUTES* pAttributes);
HRESULT IWVQueuePair::Modify(__in WV_QP_ATTRIBUTES* pAttributes,
			     __in DWORD Options,
			     __in OVERLAPPED* pOverlapped);
HRESULT IWVQueuePair::PostSend(__in WV_SEND_REQUEST* pRequest,
			       __out_opt WV_SEND_REQUEST** ppFailedRequest);
HRESULT IWVQueuePair::PostReceive(__in WV_RECEIVE_REQUEST* pRequest,
				  __out_opt WV_RECEIVE_REQUEST** ppFailedRequest);
HRESULT IWVQueuePair::BindMemoryWindow(__in IWVMemoryWindow* pMw,
				       __in WV_MR_HANDLE hMr,
				       __in UINT64 WrID,
				       __in DWORD AccessFlags,
				       __in DWORD SendFlags,
				       __in const VOID* pBuffer,
				       __in SIZE_T BufferLength,
				       __out UINT32 *RKey);
HRESULT IWVQueuePair::AttachMulticast(__in WV_GID *pGid,
				      __in UINT16 LID);
HRESULT IWVQueuePair::DetachMulticast(__in WV_GID *pGid,
				      __in UINT16 LID);
HRESULT IWVQueuePair::Notify(__in OVERLAPPED* pOverlapped);
HRESULT IWVQueuePair::GetEvent(__in WV_QP_EVENT* pEvent);


#undef INTERFACE
#define INTERFACE IWVProtectionDomain
DEFINE_GUID(IID_IWVProtectionDomain, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVProtectionDomain, IUnknown)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVProtectionDomain methods
};
HRESULT IWVProtectionDomain::CreateSharedReceiveQueue(__in WV_SRQ_ATTRIBUTES* pAttributes,
						      __out IWVSharedReceiveQueue** ppSrq);
HRESULT IWVProtectionDomain::CreateQueuePair(__in WV_QP_CREATE* pAttributes,
					     __out IWVQueuePair** ppQp);
HRESULT IWVProtectionDomain::RegisterMemory(__in const VOID* pBuffer,
					    __in SIZE_T BufferLength,
					    __in DWORD AccessFlags,
					    __in OVERLAPPED* pOverlapped,
					    __out WV_MR_HANDLE* phMr,
					    __out UINT32* pLKey,
					    __out UINT32* pRKey);
HRESULT IWVProtectionDomain::DeregisterMemory(__in WV_MR_HANDLE hMr,
					      __in OVERLAPPED* pOverlapped);
HRESULT IWVProtectionDomain::AllocateMemoryWindow(__out IWVMemoryWindow** ppMw)
HRESULT IWVProtectionDomain::CreateAddressHandle(__in WV_ADDRESS_VECTOR* pAddress,
						 __out IWVAddressHandle** ppAh);


#undef INTERFACE
#define INTERFACE IWVEndpoint
DEFINE_GUID(IID_IWVEndpoint, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVEndpoint, IWVOverlapped)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    __override STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    __override STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;

    // IWVEndpoint methods
};
// attaches ep to device and device port if not ANY, reserves TCP/UDP port
HRESULT IWVEndpoint::BindAddress(__in const struct sockaddr* pAddress);
// BindAddress (if not already bound)
// Convert addresses to transport addresses, assign source address based on
// local routing tables if no source address is given
HRESULT IWVEndpoint::ResolveAddress(__in_opt const struct sockaddr* pSourceAddress,
				    __in const struct sockaddr* pDestinationAddress,
				    __in DWORD Milliseconds,
				    __in OVERLAPPED* pOverlapped);
// IB - PR lookup - must have resolved address
HRESULT IWVEndpoint::ResolveRoute(__in DWORD Milliseconds,
				  __in OVERLAPPED* pOverlapped);
// endpoint must be bound to a device port
HRESULT IWVEndpoint::CreateQueuePair(__in IWVProtectionDomain* pPd,
				     __in WV_QP_CREATE* pAttributes,
				     __out IWVQueuePair** ppQp);
// reject a connection request or response
HRESULT IWVEndpoint::Reject(__in_opt const VOID* pPrivateData,
			    __in SIZE_T PrivateDataLength);


#undef INTERFACE
#define INTERFACE IWVConnectEndpoint
DEFINE_GUID(IID_IWVConnectEndpoint, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVConnectEndpoint, IWVEndpoint)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    __override STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    __override STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;

    // IWVConnectEndpoint methods
};
// sends connection request - must first resolve address and route
HRESULT IWVConnectEndpoint::Connect(__in WV_CONNECT_PARAM* pParam,
				    __in OVERLAPPED* pOverlapped);
// accept a connection request or response
HRESULT IWVConnectEndpoint::Accept(__in WV_CONNECT_PARAM* pParam,
				   __in OVERLAPPED* pOverlapped);
// disconnects connection
// not sure overlapped is needed (could handle internally)
HRESULT IWVConnectEndpoint::Disconnect(__in OVERLAPPED* pOverlapped);
// get endpoint info, returned info depends on state of connection process
HRESULT IWVConnectEndpoint::Query(__inout WV_CONNECT_ATTRIBUTES* pAttributes);


#undef INTERFACE
#define INTERFACE IWVDatagramEndpoint
DEFINE_GUID(IID_IWVDatagramEndpoint, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVDatagramEndpoint, IWVEndpoint)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    __override STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    __override STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;

    // IWVDatagramEndpoint methods
};
// looks up passive QP info - must first resolve address and route
HRESULT IWVDatagramEndpoint::Lookup(__in_opt const VOID* pPrivateData,
				    __in SIZE_T PrivateDataLength,
				    __in OVERLAPPED* pOverlapped);
// accept a lookup request
HRESULT IWVDatagramEndpoint::Accept(__in WV_DATAGRAM_PARAM* pParam,
				    __in OVERLAPPED* pOverlapped);
HRESULT IWVDatagramEndpoint::JoinMulticast(__in const struct sockaddr* pAddress,
					   __in OVERLAPPED* pOverlapped);
// not sure overlapped is needed (handle internally)
HRESULT IWVDatagramEndpoint::LeaveMulticast(__in const struct sockaddr* pAddress,
					    __in OVERLAPPED* pOverlapped);
// get endpoint info, returned info depends on state of connection process
HRESULT IWVDatagramEndpoint::Query(__inout WV_DATAGRAM_ATTRIBUTES* pAttributes);


#undef INTERFACE
#define INTERFACE IWVListen
DEFINE_GUID(IID_IWVListen, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVListen, IWVOverlapped)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    __override STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    __override STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;

    // IWVListen methods
};
HRESULT IWVListen::Accept(__in IWVEndpoint* pEndpoint,
			  __in OVERLAPPED* pOverlapped);


#undef INTERFACE
#define INTERFACE IWVDevice
DEFINE_GUID(IID_IWVDevice, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVDevice, IWVOverlapped)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVOverlapped methods
    __override STDMETHOD(CancelOverlappedRequests)(
        THIS
        ) PURE;

    __override STDMETHOD(GetOverlappedResult)(
        THIS_
        __inout_opt OVERLAPPED *pOverlapped,
        __out SIZE_T *pNumberOfBytesTransferred,
        __in BOOL bWait
        ) PURE;

    // IWVDevice methods
};
HRESULT IWVDevice::Query(__in WV_DEVICE_ATTRIBUTES* pAttributes,
			 __inout SIZE_T* pBufferSize);
HRESULT IWVDevice::CreateCompletionQueue(__inout SIZE_T *pEntries,
					 __out IWCompletionQueue** ppCq);
HRESULT IWVDevice::AllocateProtectionDomain(void);
HRESULT IWVDevice::Notify(__in OVERLAPPED* pOverlapped);
HRESULT IWVDevice::GetEvent(__in WV_DEVICE_EVENT* pEvent);


#undef INTERFACE
#define INTERFACE IWVProvider
DEFINE_GUID(IID_IIWVProvider, 0); // TODO: need GUID

DECLARE_INTERFACE_(IWVProvider, IUnknown)
{
    // IUnknown methods
    __override STDMETHOD(QueryInterface)(
        THIS_
        REFIID riid,
        LPVOID FAR* ppvObj
        ) PURE;

    __override STDMETHOD_(ULONG,AddRef)(
        THIS
        ) PURE;

    __override STDMETHOD_(ULONG,Release)(
        THIS
        ) PURE;

    // IWVProvider methods
};
HRESULT IWVProvider::QueryDeviceList(__inout_opt UINT64* pGuidList,
				     __inout SIZE_T* pBufferSize);
HRESULT IWVProvider::QueryDevice(__in UINT64 Guid,
				 __in WV_DEVICE_ATTRIBUTES* pAttributes,
				 __inout SIZE_T* pBufferSize);
HRESULT IWVProvider::QueryAddressList(__inout_opt WV_ADDRESS_LIST* pAddressList,
				      __inout SIZE_T* pBufferSize);
HRESULT IWVProvider::OpenDevice(__in UINT64 Guid,
				__out IWVDevice** ppDevice);
HRESULT IWVProvider::CreateConnectEndpoint(__out IWVConnectEndpoint** ppConnectEndpoint);
HRESULT IWVProvider::CreateDatagramEndpoint(__out IWVDatagramEndpoint** ppDatagramEndpoint);
HRESULT IWVProvider::CreateListen(__in const struct sockaddr* pAddress,
				  __in SIZE_T backlog,
				  __out IWVListen** ppListen);

#endif // _WINVERBS_H_





More information about the ofw mailing list