[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