[ofw] NDv2 provider patch

Fab Tillier ftillier at microsoft.com
Fri Jul 23 22:02:59 PDT 2010


Hi Sean,

The latest doc for NDv2 is available here, the header is in the appendix:
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=0fe51823-660d-489c-9c48-fd50d9f54377

Attached is a patch that updates the ND provider you had started working on, to match the new header.  I haven't tested this yet, but it does build.  Here's the scope of the changes, I apologize for not breaking it down into smaller pieces:

1. Put everything in a namespace, as a preliminary step to get rid of the 'CND' prefix to all the class names.  This way everything is nicely scoped, with no risk of collision.
2. Use a private heap, not the default process heap
3. Reorganized the class definitions to list member variables first, then member functions.
4. Made constructor and initializer private - only the factory functions should access those, and they are static members of the class so no problem there.
5. Moved all member variables to private access, and defined accessors for them.
6. Added a template class to help manage references on objects and interfaces.  This makes error handling easier - you just return and if you didn't explicitly detached the object from its container, the reference is released.
7. Removed all destructors (the auto_ref class now handles releasing any member objects)
8. Made all non-optional (i.e. cannot be NULL) parameters passed as references, rather than pointers.  Avoids the need for asserts, and requires a real object at compile time.
9. Cleaned up the casts to use C++ casting syntax, which makes it easier to search the codebase for casts in the future.
10. No longer link with the CRT.
11. Use precompiled headers, it speeds up the build (at least it did on my machine.)

I think that covers it...

This patch should be applied to the ulp\netdirect2 directory.

Signed-off-by: Fab Tillier <ftillier at microsoft.com>

Index: user/nd_base.h
===================================================================
--- user/nd_base.h      (revision 2848)
+++ user/nd_base.h      (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,35 +33,113 @@
 #ifndef _ND_BASE_H_
 #define _ND_BASE_H_

-#include <windows.h>
-#include <rdma\winverbs.h>
-#include <stdio.h>

-class CNDBase
+namespace WinVerbs {
+namespace NetworkDirect {
+
+
+template<class T>
+class auto_ref
 {
+       T* m_pObj;
+
 public:
+       auto_ref( T* pObj ) :
+               m_pObj( pObj )
+       {
+               if( m_pObj != NULL ){
+                       m_pObj->AddRef();
+               }
+       }
+       auto_ref( const auto_ref& r ) :
+               m_pObj( r.m_pObj )
+       {
+               if( m_pObj != NULL ){
+                       m_pObj->AddRef();
+               }
+       }
+       ~auto_ref()
+       {
+               if( m_pObj != NULL ){
+                       m_pObj->Release();
+               }
+       }
+
+       T* operator ->() const { return m_pObj; }
+       T* detach(){ T* tmp = m_pObj; m_pObj = NULL; return tmp; }
+       T* get() const { return m_pObj; }
+       T** ref(){ return &m_pObj; }
+       VOID** ppvObj(){ return reinterpret_cast<void**>(ref()); }
+
+       auto_ref& operator =( T* pObj )
+       {
+               if( m_pObj != NULL )
+               {
+                       m_pObj->Release();
+               }
+               m_pObj = pObj;
+               return *this;
+       }
+
+       auto_ref& operator =( const auto_ref& r )
+       {
+               if( m_pObj != NULL )
+               {
+                       m_pObj->Release();
+               }
+               m_pObj = r.get();
+               if( m_pObj != NULL )
+               {
+                       m_pObj->AddRef();
+               }
+               return *this;
+       }
+
+};
+
+
+class CNDBase
+{
+       static volatile LONG m_nObj;
+       volatile LONG m_nRef;
+
+protected:
        CNDBase();
-       ~CNDBase() {};
+       virtual ~CNDBase();
+
+private:
+       // Nobody should use these.
+       CNDBase( const CNDBase& copyFromMe );
+       CNDBase& operator =(const CNDBase& copyFromMe );
+
+public:
        STDMETHODIMP_(ULONG) AddRef();
        STDMETHODIMP_(ULONG) Release();

-       virtual void Delete() {};
+       static LONG ObjCount(){ return m_nObj; }
+};

-       volatile LONG                   m_nRef;

-protected:
-};
+extern HANDLE g_hHeap;
+
+HRESULT NDConvertWVStatus(HRESULT hr);
+
+} // namespace NetworkDirect
+} // namespace WinVerbs

 __inline void* __cdecl operator new(size_t size)
 {
-       return HeapAlloc(GetProcessHeap(), 0, size);
+       return ::HeapAlloc(WinVerbs::NetworkDirect::g_hHeap, 0, size);
 }

-__inline void __cdecl operator delete(void *pObj)
+__inline void* __cdecl operator new(size_t, void* p)
 {
-       HeapFree(GetProcessHeap(), 0, pObj);
+       return p;
 }

-HRESULT NDConvertWVStatus(HRESULT hr);
+__inline void __cdecl operator delete(void *pObj)
+{
+       ::HeapFree(WinVerbs::NetworkDirect::g_hHeap, 0, pObj);
+}

 #endif // _ND_BASE_H_
Index: user/nd_qp.cpp
===================================================================
--- user/nd_qp.cpp      (revision 2848)
+++ user/nd_qp.cpp      (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,97 +28,79 @@
  * SOFTWARE.
  */

-#include "nd_qp.h"
+
+#include "precomp.h"
+#include "nd_base.h"
+#include "nd_provider.h"
 #include "nd_adapter.h"
-#include "nd_connect.h"
 #include "nd_cq.h"
+#include "nd_srq.h"
 #include "nd_mw.h"
-#include <netinet/in.h>
+#include <InitGuid.h>
+#include "nd_qp.h"


-CNDQueuePair::CNDQueuePair(CNDAdapter *pAdapter)
+namespace WinVerbs {
+namespace NetworkDirect {
+
+CNDQueuePair::CNDQueuePair(CNDAdapter& adapter,
+                                                  CNDCompletionQueue& receiveCompletionQueue,
+                                                  CNDCompletionQueue& initiatorCompletionQueue,
+                                                  CNDSharedReceiveQueue *pSharedReceiveQueue) :
+       m_pAdapter( &adapter ),
+       m_pWvQp( NULL ),
+       m_pReceiveCq( &receiveCompletionQueue ),
+       m_pSendCq( &initiatorCompletionQueue ),
+       m_pSrq( pSharedReceiveQueue )
 {
-       pAdapter->AddRef();
-       m_pAdapter = pAdapter;
-       m_pWvQp = NULL;
-       m_pReceiveCq = NULL;
-       m_pSendCq = NULL;
 }

 STDMETHODIMP CNDQueuePair::
-Init(CNDCompletionQueue* pReceiveCompletionQueue,
-        CNDCompletionQueue* pInitiatorCompletionQueue,
-        CNDSharedReceiveQueue *pSharedReceiveQueue,
-        VOID* context, DWORD receiveQueueDepth, DWORD initiatorQueueDepth,
+Init(VOID* context, DWORD receiveQueueDepth, DWORD initiatorQueueDepth,
         DWORD maxReceiveRequestSGE, DWORD maxInitiatorRequestSGE)
 {
        WV_QP_CREATE create;
        WV_QP_ATTRIBUTES attr;
        //WV_DEVICE_ADDRESS *addr;
-       DWORD opts;
-       HRESULT hr;

-       RtlZeroMemory(&create, sizeof create);
-       m_pReceiveCq = pReceiveCompletionQueue;
-       m_pSendCq = pInitiatorCompletionQueue;
-       m_pReceiveCq->AddRef();
-       m_pSendCq->AddRef();
-       if ((m_pSrq = pSharedReceiveQueue)) {
-               m_pSrq->AddRef();
-               create.pSharedReceiveQueue = m_pSrq->m_pWvSrq;
+       ::RtlZeroMemory(&create, sizeof create);
+       if (m_pSrq.get() != NULL) {
+               create.pSharedReceiveQueue = m_pSrq->Srq();
        }

-       create.pSendCq = m_pSendCq->m_pWvCq;
-       create.pReceiveCq = m_pReceiveCq->m_pWvCq;
+       create.pSendCq = m_pSendCq->Cq();
+       create.pReceiveCq = m_pReceiveCq->Cq();
        create.Context = context;
        create.SendDepth = initiatorQueueDepth;
        create.SendSge = maxInitiatorRequestSGE;
        create.ReceiveDepth = receiveQueueDepth;
        create.ReceiveSge = maxReceiveRequestSGE;
-       //create.InitiatorDepth = ???;
-       //create.ResponderResources = ???;
-       create.MaxInlineSend = m_pAdapter->m_MaxInlineSend;
+       create.MaxInlineSend = m_pAdapter->MaxInlineSend();
        create.QpType = WvQpTypeRc;

-       hr = m_pAdapter->m_pWvPd->CreateConnectQueuePair(&create, &m_pWvQp);
+       HRESULT hr = m_pAdapter->Pd()->CreateConnectQueuePair(&create, m_pWvQp.ref());
        if (FAILED(hr)) {
                return NDConvertWVStatus(hr);
        }

-       opts = WV_QP_ATTR_STATE | WV_QP_ATTR_PORT_NUMBER | WV_QP_ATTR_PKEY_INDEX;
+       DWORD opts = WV_QP_ATTR_STATE | WV_QP_ATTR_PORT_NUMBER | WV_QP_ATTR_PKEY_INDEX;
        attr.QpState = WvQpStateInit;
+       // Use pkey index 0, and port 1 as defaults.  They can be updated when
+       // transitioning to RTR with an additional init to init transition.
+       attr.PkeyIndex = 0;
+       attr.AddressVector.PortNumber = 1;
+
        //??? need pkey and port for adapter
        //addr = &m_pAdapter->m_DevAddress;
        //attr.AddressVector.PortNumber = addr->PortNumber;
        //hr = m_pConnector->m_pAdapter->m_pWvDevice->FindPkey(addr->PortNumber, addr->Pkey,
        //                                                                                                       &attr.PkeyIndex);
-       if (FAILED(hr)) {
-               return NDConvertWVStatus(hr);
-       }
-
-       hr = m_pWvQp->Modify(&attr, opts, NULL);
-       if (FAILED(hr)) {
-               return NDConvertWVStatus(hr);
-       }
-
-       return ND_SUCCESS;
-}
+       //if (FAILED(hr)) {
+       //      return NDConvertWVStatus(hr);
+       //}

-CNDQueuePair::~CNDQueuePair()
-{
-       if (m_pWvQp != NULL) {
-               m_pWvQp->Release();
-       }
-       if (m_pReceiveCq != NULL) {
-               m_pReceiveCq->Release();
-       }
-       if (m_pSendCq != NULL) {
-               m_pSendCq->Release();
-       }
-       if (m_pSrq != NULL) {
-               m_pSrq->Release();
-       }
-       m_pAdapter->Release();
+       hr = NDConvertWVStatus(m_pWvQp->Modify(&attr, opts, NULL));
+       return hr;
 }

 STDMETHODIMP CNDQueuePair::
@@ -148,8 +131,9 @@ Release(void)
 STDMETHODIMP CNDQueuePair::
 Flush(void)
 {
-       //??? Modify QP to error state
-       return ND_NOT_SUPPORTED;
+       WV_QP_ATTRIBUTES attr;
+       attr.QpState = WvQpStateError;
+       return NDConvertWVStatus(m_pWvQp->Modify( &attr, WV_QP_ATTR_STATE, NULL ));
 }

 STDMETHODIMP_(DWORD) CNDQueuePair::
@@ -173,76 +157,89 @@ ConvertSendFlags(DWORD Flags)
 }

 STDMETHODIMP CNDQueuePair::
-Send(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE, DWORD flags)
+Send(VOID* requestContext, const ND_SGE* pSge, DWORD nSge, DWORD flags)
 {
        HRESULT hr;

-       hr = m_pWvQp->Send((UINT64) (ULONG_PTR) requestContext, (WV_SGE *) pSGE, nSGE,
+       hr = m_pWvQp->Send(reinterpret_cast<ULONG_PTR>(requestContext),
+                                          reinterpret_cast<WV_SGE*>(const_cast<ND_SGE*>(pSge)), nSge,
                                           ConvertSendFlags(flags), 0);
        return NDConvertWVStatus(hr);
 }

 STDMETHODIMP CNDQueuePair::
-Receive(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE)
+Receive(VOID* requestContext, const ND_SGE* pSge, DWORD nSge)
 {
        HRESULT hr;

-       hr = m_pWvQp->PostReceive((UINT64) (ULONG_PTR) requestContext, (WV_SGE *) pSGE, nSGE);
+       hr = m_pWvQp->PostReceive(reinterpret_cast<ULONG_PTR>(requestContext),
+                                                         reinterpret_cast<WV_SGE*>(const_cast<ND_SGE*>(pSge)),
+                                                         nSge);
        return NDConvertWVStatus(hr);
 }

 STDMETHODIMP CNDQueuePair::
-Bind(VOID* requestContext, INDMemoryRegion* pMemoryRegion,
-        INDMemoryWindow* pMemoryWindow, const VOID* pBuffer, SIZE_T cbBuffer,
+Bind(VOID* requestContext, IUnknown* pMemoryRegion,
+        IUnknown* pMemoryWindow, const VOID*, SIZE_T,
         DWORD flags)
 {
-       CNDMemoryRegion *mr = (CNDMemoryRegion *) pMemoryRegion;
-       CNDMemoryWindow *mw = (CNDMemoryWindow *) pMemoryWindow;
-       HRESULT hr;
+       CNDMemoryRegion *mr;
+       HRESULT hr = pMemoryRegion->QueryInterface( IID_NDoWVMr, reinterpret_cast<void**>(&mr) );
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_2;
+       }

-       if (mw->m_pMr != NULL) {
-               mw->m_pMr->Release();
+       CNDMemoryWindow *mw;
+       hr = pMemoryWindow->QueryInterface( IID_NDoWVMw, reinterpret_cast<void**>(&mw) );
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_3;
        }
-       mw->m_pMr = mr;
-       mr->AddRef();
-       hr = m_pWvQp->Write((UINT64) (ULONG_PTR) requestContext, NULL, 0,
+
+       mw->SetMr( mr );
+
+       hr = m_pWvQp->Write(reinterpret_cast<ULONG_PTR>(requestContext), NULL, 0,
                                                ConvertSendFlags(flags), 0, 0, 0);
        return NDConvertWVStatus(hr);
 }

 STDMETHODIMP CNDQueuePair::
-Invalidate(VOID* requestContext, INDMemoryWindow* pMemoryWindow, DWORD flags)
+Invalidate(VOID* requestContext, IUnknown* pMemoryWindow, DWORD flags)
 {
-       CNDMemoryWindow *mw = (CNDMemoryWindow *) pMemoryWindow;
-       HRESULT hr;
+       CNDMemoryWindow *mw;
+       HRESULT hr = pMemoryWindow->QueryInterface( IID_NDoWVMw, reinterpret_cast<void**>(&mw) );
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_2;
+       }

-       mw->m_pMr->Release();
-       mw->m_pMr = NULL;
-       hr = m_pWvQp->Write((UINT64) (ULONG_PTR) requestContext, NULL, 0,
+       mw->SetMr( NULL );
+       hr = m_pWvQp->Write(reinterpret_cast<ULONG_PTR>(requestContext), NULL, 0,
                                                ConvertSendFlags(flags), 0, 0, 0);
        return NDConvertWVStatus(hr);
 }

 STDMETHODIMP CNDQueuePair::
-Read(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE,
+Read(VOID* requestContext, const ND_SGE* pSge, DWORD nSge,
         UINT64 remoteAddress, UINT32 remoteToken, DWORD flags)
 {
-       DWORD opts;
        HRESULT hr;

-       hr = m_pWvQp->Read((UINT64) (ULONG_PTR) requestContext, (WV_SGE *) pSGE, nSGE,
-                                          ConvertSendFlags(flags), htonll(remoteAddress), remoteToken);
+       hr = m_pWvQp->Read(reinterpret_cast<ULONG_PTR>(requestContext),
+                                          reinterpret_cast<WV_SGE*>(const_cast<ND_SGE*>(pSge)), nSge,
+                                          ConvertSendFlags(flags), _byteswap_uint64(remoteAddress), remoteToken);
        return NDConvertWVStatus(hr);
 }

 STDMETHODIMP CNDQueuePair::
-Write(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE,
+Write(VOID* requestContext, const ND_SGE* pSge, DWORD nSge,
          UINT64 remoteAddress, UINT32 remoteToken, DWORD flags)
 {
-       DWORD opts;
        HRESULT hr;

-       hr = m_pWvQp->Write((UINT64) (ULONG_PTR) requestContext, (WV_SGE *) pSGE, nSGE,
-                                           ConvertSendFlags(flags), 0, htonll(remoteAddress), remoteToken);
+       hr = m_pWvQp->Write(reinterpret_cast<ULONG_PTR>(requestContext),
+                                               reinterpret_cast<WV_SGE*>(const_cast<ND_SGE*>(pSge)), nSge,
+                                               ConvertSendFlags(flags), 0, _byteswap_uint64(remoteAddress), remoteToken);
        return NDConvertWVStatus(hr);
 }
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
Index: user/nd_adapter.cpp
===================================================================
--- user/nd_adapter.cpp (revision 2848)
+++ user/nd_adapter.cpp (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,25 +28,48 @@
  * SOFTWARE.
  */

+#include "precomp.h"
+#include "nd_base.h"
+#include "nd_provider.h"
 #include "nd_adapter.h"
 #include "nd_cq.h"
-#include "nd_listen.h"
-#include "nd_connect.h"
 #include "nd_mw.h"
-#include "nd_qp.h"
 #include "nd_srq.h"
+#include "nd_qp.h"
 #include "nd_ep.h"
+#include "nd_connect.h"
+#include "nd_listen.h"

-CNDAdapter::CNDAdapter(CNDProvider *pProvider)
+
+namespace WinVerbs {
+namespace NetworkDirect {
+
+CNDAdapter::CNDAdapter(CNDProvider &provider) :
+       m_pProvider( &provider ),
+       m_pWvDevice( NULL ),
+       m_pWvPd( NULL ),
+       m_MaxInlineSend( 0 ),
+       m_DeviceGuid( 0 )
 {
-       pProvider->AddRef();
-       m_pProvider = pProvider;
-       m_pWvDevice = NULL;
-       m_pWvPd = NULL;
-       m_MaxInlineSend = 0;
 }

-STDMETHODIMP CNDAdapter::
+HRESULT CNDAdapter::
+CreateInstance( CNDProvider& provider, UINT64 adapterId, VOID** ppAdapter)
+{
+       auto_ref<CNDAdapter> adapter(new CNDAdapter(provider));
+       if (adapter.get() == NULL) {
+               return E_OUTOFMEMORY;
+       }
+
+       HRESULT hr = adapter->Init(adapterId);
+       if (SUCCEEDED(hr)) {
+               *ppAdapter = adapter.detach();
+       }
+
+       return hr;
+}
+
+HRESULT CNDAdapter::
 Init(UINT64 adapterId)
 {
        HRESULT hr;
@@ -53,32 +77,21 @@ Init(UINT64 adapterId)
        DWORD ret;

        m_DeviceGuid = adapterId;
-       hr = m_pProvider->m_pWvProvider->OpenDevice(m_DeviceGuid, &m_pWvDevice);
+       hr = m_pProvider->Prov()->OpenDevice(m_DeviceGuid, m_pWvDevice.ref());
        if (FAILED(hr)) {
                return NDConvertWVStatus(hr);
        }

-       hr = m_pWvDevice->AllocateProtectionDomain(&m_pWvPd);
+       hr = m_pWvDevice->AllocateProtectionDomain(m_pWvPd.ref());
        if (FAILED(hr)) {
                return NDConvertWVStatus(hr);
        }

-       ret = GetEnvironmentVariable("IBNDPROV_MAX_INLINE_SIZE", val, 16);
-       m_MaxInlineSend = (ret > 0 && ret <= 16) ? (SIZE_T) strtoul(val, NULL, 16) : 160;
+       ret = GetEnvironmentVariable(TEXT("IBNDPROV_MAX_INLINE_SIZE"), val, 16);
+       m_MaxInlineSend = (ret > 0 && ret <= 16) ? (SIZE_T) _tcstoul(val, NULL, 16) : 160;
        return ND_SUCCESS;
 }

-CNDAdapter::~CNDAdapter(void)
-{
-       if (m_pWvPd != NULL) {
-               m_pWvPd->Release();
-       }
-       if (m_pWvDevice != NULL) {
-               m_pWvDevice->Release();
-       }
-       m_pProvider->Release();
-}
-
 STDMETHODIMP CNDAdapter::
 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
 {
@@ -87,8 +100,8 @@ QueryInterface(REFIID riid, LPVOID FAR*
                return E_NOINTERFACE;
        }

-       *ppvObj = this;
        AddRef();
+       *ppvObj = this;
        return ND_SUCCESS;
 }

@@ -107,7 +120,7 @@ Release(void)
 STDMETHODIMP_(HANDLE) CNDAdapter::
 GetFileHandle(void)
 {
-       return m_pProvider->m_pWvProvider->GetFileHandle();
+       return m_pProvider->Prov()->GetFileHandle();
 }

 STDMETHODIMP CNDAdapter::
@@ -116,18 +129,18 @@ Query(ND_ADAPTER_INFO* pInfo, SIZE_T* pc
        WV_DEVICE_ATTRIBUTES attr;
        HRESULT hr;

-       if (pInfo != NULL && pInfo->InfoVersion != 1) {
-               return ND_NOT_SUPPORTED;
+       if (*pcbInfo < sizeof(ND_ADAPTER_INFO)) {
+               *pcbInfo = sizeof(ND_ADAPTER_INFO);
+               return ND_BUFFER_OVERFLOW;
        }

-       if (*pcbInfo < sizeof(ND_ADAPTER_INFO)) {
-               hr = ND_BUFFER_OVERFLOW;
-               goto out;
+       if (pInfo != NULL && pInfo->InfoVersion != 1) {
+               return ND_NOT_SUPPORTED;
        }

-       hr = m_pWvDevice->Query(&attr);
+       hr = NDConvertWVStatus( m_pWvDevice->Query(&attr) );
        if (FAILED(hr)) {
-               goto out;
+               return hr;
        }

        pInfo->VendorId                                 = (UINT16) attr.VendorId;
@@ -135,29 +148,29 @@ Query(ND_ADAPTER_INFO* pInfo, SIZE_T* pc
        pInfo->AdapterId                                = m_DeviceGuid;
        pInfo->MaxRegistrationSize              = attr.MaxMrSize;
        pInfo->MaxWindowSize                    = attr.MaxMrSize;
-    pInfo->MaxReceiveSGE                       = (DWORD) attr.MaxSge;
-    pInfo->MaxInitiatorSGE                     = (DWORD) attr.MaxSge;
-    pInfo->MaxReadSGE                          = (DWORD) attr.MaxSge;
-    pInfo->MaxTransferLength           = 1 << 31;
+       pInfo->MaxReceiveSge                    = (DWORD) attr.MaxSge;
+       pInfo->MaxInitiatorSge                  = (DWORD) attr.MaxSge;
+       pInfo->MaxReadSge                               = (DWORD) attr.MaxSge;
+       //TODO: The MaxTransferLength needs to be accurate - not all devices support 2GB.
+       pInfo->MaxTransferLength                = 1UL << 31;
        pInfo->MaxInboundReadLimit              = (DWORD) attr.MaxQpResponderResources;
        pInfo->MaxOutboundReadLimit             = (DWORD) attr.MaxQpInitiatorDepth;
-    pInfo->MaxRQDepth                          = (DWORD) attr.MaxQpWr;
-    pInfo->MaxIQDepth                          = (DWORD) attr.MaxQpWr;
-    pInfo->MaxSRQDepth                         = (DWORD) attr.MaxSrqWr;
-    pInfo->MaxCQDepth                          = (DWORD) attr.MaxCqEntries;
-    pInfo->InlineRequestThreshold      = m_MaxInlineSend;
-    pInfo->LargeRequestThreshold       = 0;
-       pInfo->MaxCallerData                    = ND_PRIVATE_DATA_SIZE;
-       pInfo->MaxCalleeData                    = ND_PRIVATE_DATA_SIZE;
-    pInfo->InlineDataFactor                    = 0;
-    pInfo->InlineDataAdjustment                = -((LONG) attr.MaxInlineSend);
-    pInfo->InOrderDMA                          = TRUE;
-    pInfo->SupportsCQResize                    = TRUE;
-    pInfo->SupportsLoopbackConnections = TRUE;
+       pInfo->MaxReceiveQueueDepth             = (DWORD) attr.MaxQpWr;
+       pInfo->MaxInitiatorQueueDepth   = (DWORD) attr.MaxQpWr;
+       pInfo->MaxSharedReceiveQueueDepth       = (DWORD) attr.MaxSrqWr;
+       pInfo->MaxCompletionQueueDepth  = (DWORD) attr.MaxCqEntries;
+       pInfo->InlineRequestThreshold   = m_MaxInlineSend;
+       pInfo->LargeRequestThreshold    = 0;
+       pInfo->MaxCallerData                    = RTL_FIELD_SIZE(WV_CONNECT_PARAM, Data);
+       pInfo->MaxCalleeData                    = RTL_FIELD_SIZE(WV_CONNECT_PARAM, Data);
+       pInfo->InlineDataFactor                 = 0;
+       pInfo->InlineDataAdjustment             = -((LONG) attr.MaxInlineSend);
+       pInfo->InOrderDMA                               = TRUE;
+       pInfo->SupportsCQResize                 = TRUE;
+       pInfo->SupportsLoopbackConnections = TRUE;

-out:
        *pcbInfo = sizeof(ND_ADAPTER_INFO);
-       return NDConvertWVStatus(hr);
+       return ND_SUCCESS;
 }

 STDMETHODIMP CNDAdapter::
@@ -167,80 +180,136 @@ QueryAddressList(SOCKET_ADDRESS_LIST* pA
 }

 STDMETHODIMP CNDAdapter::
-CreateCompletionQueue(DWORD queueDepth, GROUP_AFFINITY* pAffinity,
-                                         INDCompletionQueue** ppCompletionQueue)
+CreateCompletionQueue(REFIID iid, DWORD queueDepth, USHORT group,
+                                         KAFFINITY affinity, VOID** ppCompletionQueue)
 {
-       return CNDCompletionQueue::CreateInstance(this, queueDepth, ppCompletionQueue);
+       if( iid != IID_INDCompletionQueue ){
+               return E_NOINTERFACE;
+       }
+       return CNDCompletionQueue::CreateInstance(*this, queueDepth, group, affinity, ppCompletionQueue);
 }

 STDMETHODIMP CNDAdapter::
-CreateMemoryRegion(INDMemoryRegion** ppMemoryRegion)
+CreateMemoryRegion(REFIID iid, VOID** ppMemoryRegion)
 {
-       return CNDMemoryRegion::CreateInstance(this, ppMemoryRegion);
+       if( iid != IID_INDMemoryRegion ){
+               return E_NOINTERFACE;
+       }
+       return CNDMemoryRegion::CreateInstance(*this, ppMemoryRegion);
 }

 STDMETHODIMP CNDAdapter::
-CreateMemoryWindow(INDMemoryWindow** ppMemoryWindow)
+CreateMemoryWindow(REFIID iid, VOID** ppMemoryWindow)
 {
-       return CNDMemoryWindow::CreateInstance(this, ppMemoryWindow);
+       if( iid != IID_INDMemoryWindow ){
+               return E_NOINTERFACE;
+       }
+       return CNDMemoryWindow::CreateInstance(*this, ppMemoryWindow);
 }

 STDMETHODIMP CNDAdapter::
-CreateSharedReceiveQueue(DWORD queueDepth, DWORD maxSGE,
-                                                DWORD notifyThreshold, GROUP_AFFINITY* pAffinity,
-                                                INDSharedReceiveQueue** ppSharedReceiveQueue)
+CreateSharedReceiveQueue(REFIID iid, DWORD queueDepth, DWORD maxSge,
+                                                DWORD notifyThreshold, USHORT group,
+                                                KAFFINITY affinity, VOID** ppSharedReceiveQueue)
 {
-       return CNDSharedReceiveQueue::CreateInstance(this, queueDepth, maxSGE,
-                                                                                                notifyThreshold, pAffinity,
-                                                                                                ppSharedReceiveQueue);
+       if( iid != IID_INDSharedReceiveQueue ){
+               return E_NOINTERFACE;
+       }
+       return CNDSharedReceiveQueue::CreateInstance(*this, queueDepth, maxSge,
+                                                                                                notifyThreshold, group,
+                                                                                                affinity, ppSharedReceiveQueue);
 }

 STDMETHODIMP CNDAdapter::
-CreateQueuePair(INDCompletionQueue* pReceiveCompletionQueue,
-                               INDCompletionQueue* pInitiatorCompletionQueue, VOID* context,
+CreateQueuePair(REFIID iid, IUnknown* pReceiveCompletionQueue,
+                               IUnknown* pInitiatorCompletionQueue, VOID* context,
                                DWORD receiveQueueDepth, DWORD initiatorQueueDepth,
-                               DWORD maxReceiveRequestSGE, DWORD maxInitiatorRequestSGE,
-                               INDQueuePair** ppQueuePair)
+                               DWORD maxReceiveRequestSge, DWORD maxInitiatorRequestSge,
+                               VOID** ppQueuePair)
 {
-       CNDCompletionQueue *rcq = (CNDCompletionQueue *) pReceiveCompletionQueue;
-       CNDCompletionQueue *icq = (CNDCompletionQueue *) pInitiatorCompletionQueue;
+       if( iid != IID_INDQueuePair ){
+               return E_NOINTERFACE;
+       }

-       return CNDQueuePair::CreateInstance(this, rcq, icq, NULL,
+       auto_ref<CNDCompletionQueue> rcq(NULL);
+       HRESULT hr = pReceiveCompletionQueue->QueryInterface(IID_NDoWVCq, rcq.ppvObj());
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_2;
+       }
+
+       auto_ref<CNDCompletionQueue> icq(NULL);
+       hr = pInitiatorCompletionQueue->QueryInterface(IID_NDoWVCq, icq.ppvObj());
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_3;
+       }
+
+       return CNDQueuePair::CreateInstance(*this, *rcq.get(), *icq.get(), NULL,
                                                                                context, receiveQueueDepth, initiatorQueueDepth,
-                                                                               maxReceiveRequestSGE, maxInitiatorRequestSGE,
+                                                                               maxReceiveRequestSge, maxInitiatorRequestSge,
                                                                                ppQueuePair);
 }

 STDMETHODIMP CNDAdapter::
-CreateQueuePairWithSRQ(INDCompletionQueue* pReceiveCompletionQueue,
-                                          INDCompletionQueue* pInitiatorCompletionQueue,
-                                          INDSharedReceiveQueue* pSharedReceiveQueue, VOID* context,
-                                          DWORD initiatorQueueDepth, DWORD maxInitiatorRequestSGE,
-                                          INDQueuePair** ppQueuePair)
+CreateQueuePairWithSrq(REFIID iid, IUnknown* pReceiveCompletionQueue,
+                                          IUnknown* pInitiatorCompletionQueue,
+                                          IUnknown* pSharedReceiveQueue, VOID* context,
+                                          DWORD initiatorQueueDepth, DWORD maxInitiatorRequestSge,
+                                          VOID** ppQueuePair)
 {
-       CNDCompletionQueue *rcq = (CNDCompletionQueue *) pReceiveCompletionQueue;
-       CNDCompletionQueue *icq = (CNDCompletionQueue *) pInitiatorCompletionQueue;
-       CNDSharedReceiveQueue *srq = (CNDSharedReceiveQueue *) pSharedReceiveQueue;
+       if( iid != IID_INDQueuePair ){
+               return E_NOINTERFACE;
+       }

-       return CNDQueuePair::CreateInstance(this, rcq, icq, srq,
+       auto_ref<CNDCompletionQueue> rcq(NULL);
+       HRESULT hr = pReceiveCompletionQueue->QueryInterface(IID_NDoWVCq, rcq.ppvObj());
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_2;
+       }
+
+       auto_ref<CNDCompletionQueue> icq(NULL);
+       hr = pInitiatorCompletionQueue->QueryInterface(IID_NDoWVCq, icq.ppvObj());
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_3;
+       }
+
+       auto_ref<CNDSharedReceiveQueue> srq(NULL);
+       hr = pSharedReceiveQueue->QueryInterface(IID_NDoWVSrq, srq.ppvObj());
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_4;
+       }
+
+       return CNDQueuePair::CreateInstance(*this, *rcq.get(), *icq.get(), srq.get(),
                                                                                context, 0, initiatorQueueDepth, 0,
-                                                                               maxInitiatorRequestSGE, ppQueuePair);
+                                                                               maxInitiatorRequestSge, ppQueuePair);
 }

 STDMETHODIMP CNDAdapter::
-CreateSharedEndpoint(INDSharedEndpoint** ppSharedEndpoint)
+CreateSharedEndpoint(REFIID iid, VOID** ppSharedEndpoint)
 {
-       return CNDSharedEndpoint::CreateInstance(this, ppSharedEndpoint);
+       if( iid != IID_INDSharedEndpoint ){
+               return E_NOINTERFACE;
+       }
+       return CNDSharedEndpoint::CreateInstance(*this, ppSharedEndpoint);
 }

 STDMETHODIMP CNDAdapter::
-CreateConnector(INDConnector** ppConnector)
+CreateConnector(REFIID iid, VOID** ppConnector)
 {
-       return CNDConnector::CreateInstance(this, ppConnector);
+       if( iid != IID_INDConnector ){
+               return E_NOINTERFACE;
+       }
+       return CNDConnector::CreateInstance(*this, ppConnector);
 }

 STDMETHODIMP CNDAdapter::
-CreateListen(INDListen** ppListen)
+CreateListen(REFIID iid, VOID** ppListen)
 {
-       return CNDListen::CreateInstance(this, ppListen);
+       if( iid != IID_INDListen ){
+               return E_NOINTERFACE;
+       }
+       return CNDListen::CreateInstance(*this, ppListen);
 }
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
+
Index: user/SOURCES
===================================================================
--- user/SOURCES        (revision 2848)
+++ user/SOURCES        (working copy)
@@ -14,7 +14,7 @@ DLLDEF = $(OBJ_PATH)\$O\nd_export.def
 !endif

 DLLENTRY = DllMain
-USE_MSVCRT = 1
+USE_NTDLL = 1

 SOURCES =                      \
        nd_main.cpp             \
@@ -29,8 +29,11 @@ SOURCES =                    \
        nd_cq.cpp               \
        nd_srq.cpp

+PRECOMPILED_INCLUDE=precomp.h
+PRECOMPILED_CXX=1
+
 INCLUDES = ..\..\..\inc;..\..\..\inc\user;\
-                  ..\..\..\inc\user\linux;$(ND2_SDK_PATH)\include;
+                  ..\..\..\inc\user\linux;$(ND2_SDK_PATH);

 TARGETLIBS =                                           \
        $(SDK_LIB_PATH)\kernel32.lib    \
Index: user/nd_mw.cpp
===================================================================
--- user/nd_mw.cpp      (revision 2848)
+++ user/nd_mw.cpp      (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,19 +28,24 @@
  * SOFTWARE.
  */

+#include "precomp.h"
+#include "nd_base.h"
+#include "nd_provider.h"
+#include "nd_adapter.h"
+#include <InitGuid.h>
 #include "nd_mw.h"


-CNDMemoryRegion::CNDMemoryRegion(CNDAdapter *pAdapter)
-{
-       pAdapter->AddRef();
-       m_pAdapter = pAdapter;
-       RtlZeroMemory(&m_Keys, sizeof(m_Keys));
-}
+namespace WinVerbs {
+namespace NetworkDirect {

-CNDMemoryRegion::~CNDMemoryRegion()
+static const WV_MEMORY_KEYS s_zeroKeys = {0,0};
+
+CNDMemoryRegion::CNDMemoryRegion(CNDAdapter& adapter) :
+       m_pAdapter( &adapter ),
+       m_pOv( NULL ),
+       m_Keys( s_zeroKeys )
 {
-       m_pAdapter->Release();
 }

 STDMETHODIMP CNDMemoryRegion::
@@ -50,8 +56,8 @@ QueryInterface(REFIID riid, LPVOID FAR*
                return E_NOINTERFACE;
        }

-       *ppvObj = this;
        AddRef();
+       *ppvObj = this;
        return ND_SUCCESS;
 }

@@ -67,16 +73,44 @@ Release(void)
        return CNDBase::Release();
 }

-DWORD ConvertAccessFlags(DWORD Flags)
+STDMETHODIMP CNDMemoryRegion::
+CancelOverlappedRequests(void)
+{
+       OVERLAPPED* pOv = reinterpret_cast<OVERLAPPED*>(m_pOv);
+       if( pOv != NULL ){
+               ::CancelIoEx( m_pAdapter->GetFileHandle(), pOv );
+       }
+       return ND_SUCCESS;
+}
+
+STDMETHODIMP CNDMemoryRegion::
+GetOverlappedResult(OVERLAPPED *pOverlapped, BOOL bWait)
+{
+       DWORD bytes;
+       HRESULT hr = m_pAdapter->Pd()->GetOverlappedResult(pOverlapped, &bytes, bWait);
+       hr = NDConvertWVStatus(hr);
+       if( hr != ND_PENDING && pOverlapped == m_pOv ){
+               InterlockedExchangePointer( &m_pOv, NULL );
+       }
+       return hr;
+}
+
+DWORD CNDMemoryRegion::ConvertAccessFlags(DWORD Flags)
 {
        DWORD opts = 0;

        //other flags to convert???
-       if (!(Flags & ND_OP_FLAG_ALLOW_READ)) {
-               opts |= WV_ACCESS_REMOTE_READ;
+       if (!(Flags & ND_MR_FLAG_ALLOW_LOCAL_WRITE)) {
+               opts |= WV_ACCESS_LOCAL_WRITE;
        }
-       if (Flags & ND_OP_FLAG_ALLOW_WRITE) {
-               opts |= WV_ACCESS_REMOTE_WRITE;
+       if (!(Flags & ND_MR_FLAG_ALLOW_REMOTE_READ)) {
+               opts |= WV_ACCESS_REMOTE_READ | WV_ACCESS_MW_BIND;
+       }
+       if (Flags & ND_MR_FLAG_ALLOW_REMOTE_WRITE) {
+               opts |= WV_ACCESS_REMOTE_WRITE| WV_ACCESS_MW_BIND;
+       }
+       if (!(Flags & ND_MR_FLAG_DO_NOT_SECURE_VM)) {
+               opts |= WV_ACCESS_CACHABLE;
        }
        return opts;
 }
@@ -84,21 +118,36 @@ DWORD ConvertAccessFlags(DWORD Flags)
 STDMETHODIMP CNDMemoryRegion::
 Register(const VOID* pBuffer, SIZE_T cbBuffer, DWORD flags, OVERLAPPED* pOverlapped)
 {
-       HRESULT hr;
+       void* pOv = InterlockedCompareExchangePointer( &m_pOv, pOverlapped, NULL );
+       if( pOv != NULL ){
+               return ND_DEVICE_BUSY;
+       }
+       HRESULT hr = m_pAdapter->Pd()->RegisterMemory(pBuffer, cbBuffer, ConvertAccessFlags(flags),
+                                                                                                 pOverlapped, &m_Keys);
+       hr = NDConvertWVStatus(hr);
+       if( hr != ND_PENDING ){
+               InterlockedExchangePointer( &m_pOv, NULL );
+       }

-       hr = m_pAdapter->m_pWvPd->RegisterMemory(pBuffer, cbBuffer, ConvertAccessFlags(flags),
-                                                                                        pOverlapped, &m_Keys);
-       return NDConvertWVStatus(hr);
+       return hr;
 }

 STDMETHODIMP CNDMemoryRegion::
 Deregister(OVERLAPPED* pOverlapped)
 {
-       HRESULT hr;
+       void* pOv = InterlockedCompareExchangePointer( &m_pOv, pOverlapped, NULL );
+       if( pOv != NULL ){
+               return ND_DEVICE_BUSY;
+       }

        //??? if the lkey is not unique, we need to change this
-       hr = m_pAdapter->m_pWvPd->DeregisterMemory(m_Keys.Lkey, pOverlapped);
-       return NDConvertWVStatus(hr);
+       HRESULT hr = m_pAdapter->Pd()->DeregisterMemory(m_Keys.Lkey, pOverlapped);
+       hr = NDConvertWVStatus(hr);
+       if( hr != ND_PENDING ){
+               InterlockedExchangePointer( &m_pOv, NULL );
+       }
+
+       return hr;
 }

 STDMETHODIMP_(UINT32) CNDMemoryRegion::
@@ -114,16 +163,10 @@ GetRemoteToken()
 }


-CNDMemoryWindow::CNDMemoryWindow(CNDAdapter *pAdapter)
-{
-       pAdapter->AddRef();
-       m_pAdapter = pAdapter;
-       m_pMr = NULL;
-}
-
-CNDMemoryWindow::~CNDMemoryWindow()
+CNDMemoryWindow::CNDMemoryWindow(CNDAdapter& adapter) :
+       m_pAdapter( &adapter ),
+       m_pMr( NULL )
 {
-       m_pAdapter->Release();
 }

 STDMETHODIMP CNDMemoryWindow::
@@ -156,3 +199,7 @@ GetRemoteToken()
 {
        return m_pMr->GetRemoteToken();
 }
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
+
Index: user/nd_main.cpp
===================================================================
--- user/nd_main.cpp    (revision 2848)
+++ user/nd_main.cpp    (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,62 +28,85 @@
  * SOFTWARE.
  */

-#include <windows.h>
-#include <ws2spi.h>
-#include <stdio.h>
+#include <InitGuid.h>
+#include <ndspi.h>
+#include "precomp.h"
+#include "nd_base.h"
 #include "nd_provider.h"


+namespace WinVerbs {
+namespace NetworkDirect {
+
+HANDLE g_hHeap = NULL;
+
 extern "C" {

 extern BOOL APIENTRY
-_DllMainCRTStartupForGS(HINSTANCE h_module, DWORD ul_reason_for_call,
-                                               LPVOID lp_reserved);
+_DllMainCRTStartupForGS(
+       HINSTANCE h_module,
+       DWORD ul_reason_for_call,
+       LPVOID lp_reserved
+       );


 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
 {
-       switch (dwReason) {
+       switch (dwReason)
+       {
        case DLL_PROCESS_ATTACH:
+               if( _DllMainCRTStartupForGS(hInstance, dwReason, lpReserved) == FALSE )
+               {
+                       return FALSE;
+               }
+
+               g_hHeap = ::HeapCreate( 0, 0, 0 );
+               if( g_hHeap == NULL )
+               {
+                       return FALSE;
+               }
+
+               return TRUE;
+
        case DLL_PROCESS_DETACH:
+               if( g_hHeap == NULL )
+               {
+                       ::HeapDestroy( g_hHeap );
+               }
+
                return _DllMainCRTStartupForGS(hInstance, dwReason, lpReserved);
+
        default:
-               return TRUE;
+               return FALSE;
        }
 }

 STDAPI DllCanUnloadNow(void)
 {
-       return S_OK;
+       return (CNDBase::ObjCount() == 0)? S_OK : S_FALSE;
 }

 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
 {
        UNREFERENCED_PARAMETER(rclsid);

-       if (riid != IID_IClassFactory) {
+       if ( riid != IID_INDProvider )
+       {
                *ppv = NULL;
                return E_NOINTERFACE;
        }

-       *ppv = new CNDClassFactory();
-       if (*ppv == NULL) {
-               return E_OUTOFMEMORY;
-       }
-
-       return S_OK;
+       return CNDProvider::CreateInstance( ppv );
 }

-int WSPStartup(WORD wVersionRequested, LPWSPDATA lpWSPData,
-                          LPWSAPROTOCOL_INFOW lpProtocolInfo,
-                          WSPUPCALLTABLE UpcallTable, LPWSPPROC_TABLE lpProcTable)
+int /*WSPAPI*/ WSPStartup(WORD, LPWSPDATA, LPWSAPROTOCOL_INFOW, WSPUPCALLTABLE, LPWSPPROC_TABLE)
 {
-       UNREFERENCED_PARAMETER(wVersionRequested);
-       UNREFERENCED_PARAMETER(lpWSPData);
-       UNREFERENCED_PARAMETER(lpProtocolInfo);
-       UNREFERENCED_PARAMETER(UpcallTable);
-       UNREFERENCED_PARAMETER(lpProcTable);
        return WSASYSNOTREADY;
 }

-} // extern "C"
\ No newline at end of file
+} // extern "C"
+
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
+
Index: user/nd_qp.h
===================================================================
--- user/nd_qp.h        (revision 2848)
+++ user/nd_qp.h        (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,17 +33,60 @@
 #ifndef _ND_QUEUEPAIR_H_
 #define _ND_QUEUEPAIR_H_

-#include <initguid.h>
-#include <ndspi.h>
-#include "nd_base.h"
-#include "nd_cq.h"
-#include "nd_srq.h"
-#include "nd_adapter.h"

+namespace WinVerbs {
+namespace NetworkDirect {

-class CNDQueuePair : public INDQueuePair, public CNDBase
+// {1AE2602B-BCEF-4DE8-B35E-439A95223DE4}
+DEFINE_GUID(IID_NDoWVQp,
+0x1ae2602b, 0xbcef, 0x4de8, 0xb3, 0x5e, 0x43, 0x9a, 0x95, 0x22, 0x3d, 0xe4);
+
+class CNDQueuePair : public INDQueuePair, private CNDBase
 {
+       auto_ref<IWVConnectQueuePair>   m_pWvQp;
+       auto_ref<CNDAdapter>                    m_pAdapter;
+       auto_ref<CNDCompletionQueue>    m_pReceiveCq;
+       auto_ref<CNDCompletionQueue>    m_pSendCq;
+       auto_ref<CNDSharedReceiveQueue> m_pSrq;
+
+private:
+       CNDQueuePair(CNDAdapter& adapter, CNDCompletionQueue& receiveCompletionQueue,
+                                CNDCompletionQueue& initiatorCompletionQueue,
+                                CNDSharedReceiveQueue *pSharedReceiveQueue);
+
+       HRESULT Init(VOID* context, DWORD receiveQueueDepth, DWORD initiatorQueueDepth,
+                                DWORD maxReceiveRequestSGE, DWORD maxInitiatorRequestSGE);
+       DWORD ConvertSendFlags(DWORD Flags);
+
 public:
+       static STDMETHODIMP
+       CreateInstance(CNDAdapter& adapter,
+                                  CNDCompletionQueue& receiveCompletionQueue,
+                                  CNDCompletionQueue& initiatorCompletionQueue,
+                                  CNDSharedReceiveQueue *pSharedReceiveQueue,
+                                  VOID* context, DWORD receiveQueueDepth, DWORD initiatorQueueDepth,
+                                  DWORD maxReceiveRequestSGE, DWORD maxInitiatorRequestSGE,
+                                  VOID** ppQueuePair)
+       {
+               auto_ref<CNDQueuePair> qp(
+                       new CNDQueuePair(adapter,receiveCompletionQueue,
+                                                        initiatorCompletionQueue, pSharedReceiveQueue)
+                       );
+               if (qp.get() == NULL) {
+                       return ND_NO_MEMORY;
+               }
+
+               HRESULT hr = qp->Init(context, receiveQueueDepth, initiatorQueueDepth,
+                                                         maxReceiveRequestSGE, maxInitiatorRequestSGE);
+               if (SUCCEEDED(hr)) {
+                       *ppQueuePair = qp.detach();
+               }
+
+               return hr;
+       }
+
+       IWVConnectQueuePair* Qp(){return m_pWvQp.get();}
+
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
@@ -52,67 +96,19 @@ public:
        STDMETHODIMP Flush();
        STDMETHODIMP Send(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE, DWORD flags);
        STDMETHODIMP Receive(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE);
-       STDMETHODIMP Bind(VOID* requestContext, INDMemoryRegion* pMemoryRegion,
-                                         INDMemoryWindow* pMemoryWindow, const VOID* pBuffer, SIZE_T cbBuffer,
+       STDMETHODIMP Bind(VOID* requestContext, IUnknown* pMemoryRegion,
+                                         IUnknown* pMemoryWindow, const VOID* pBuffer, SIZE_T cbBuffer,
                                          DWORD flags);
-       STDMETHODIMP Invalidate(VOID* requestContext, INDMemoryWindow* pMemoryWindow, DWORD flags);
+       STDMETHODIMP Invalidate(VOID* requestContext, IUnknown* pMemoryWindow, DWORD flags);
        STDMETHODIMP Read(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE,
                                          UINT64 remoteAddress, UINT32 remoteToken, DWORD flags);
        STDMETHODIMP Write(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE,
                                           UINT64 remoteAddress, UINT32 remoteToken, DWORD flags);

-       CNDQueuePair(CNDAdapter *pAdapter);
-       ~CNDQueuePair();
-       void Delete() {delete this;}
-       static STDMETHODIMP
-       CreateInstance(CNDAdapter *pAdapter,
-                                  CNDCompletionQueue* pReceiveCompletionQueue,
-                                  CNDCompletionQueue* pInitiatorCompletionQueue,
-                                  CNDSharedReceiveQueue *pSharedReceiveQueue,
-                                  VOID* context, DWORD receiveQueueDepth, DWORD initiatorQueueDepth,
-                                  DWORD maxReceiveRequestSGE, DWORD maxInitiatorRequestSGE,
-                                  INDQueuePair** ppQueuePair)
-       {
-               HRESULT hr;
-               CNDQueuePair *qp;
-
-               qp = new CNDQueuePair(pAdapter);
-               if (qp == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err1;
-               }
-
-               hr = qp->Init(pReceiveCompletionQueue, pInitiatorCompletionQueue,
-                                         pSharedReceiveQueue, context, receiveQueueDepth,
-                                         initiatorQueueDepth, maxReceiveRequestSGE, maxInitiatorRequestSGE);
-               if (FAILED(hr)) {
-                       goto err2;
-               }
-
-               *ppQueuePair = qp;
-               return ND_SUCCESS;
-
-       err2:
-               qp->Release();
-       err1:
-               *ppQueuePair = NULL;
-               return hr;
-       }
-
-       IWVConnectQueuePair     *m_pWvQp;
+};

-protected:
-       CNDAdapter                      *m_pAdapter;
-       CNDCompletionQueue      *m_pReceiveCq;
-       CNDCompletionQueue      *m_pSendCq;
-       CNDSharedReceiveQueue *m_pSrq;
+} // namespace NetworkDirect
+} // namespace WinVerbs

-       STDMETHODIMP Init(CNDCompletionQueue* pReceiveCompletionQueue,
-                                         CNDCompletionQueue* pInitiatorCompletionQueue,
-                                         CNDSharedReceiveQueue *pSharedReceiveQueue,
-                                         VOID* context, DWORD receiveQueueDepth, DWORD initiatorQueueDepth,
-                                         DWORD maxReceiveRequestSGE, DWORD maxInitiatorRequestSGE);
-       STDMETHODIMP_(DWORD) ConvertSendFlags(DWORD Flags);
-};

 #endif // _ND_QUEUEPAIR_H_
Index: user/nd_adapter.h
===================================================================
--- user/nd_adapter.h   (revision 2848)
+++ user/nd_adapter.h   (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,14 +33,33 @@
 #ifndef _ND_ADAPTER_H_
 #define _ND_ADAPTER_H_

-#include <ndspi.h>
-#include "nd_base.h"
-#include "nd_provider.h"

+namespace WinVerbs {
+namespace NetworkDirect {

-class CNDAdapter : public INDAdapter, public CNDBase
+class CNDAdapter : public INDAdapter, private CNDBase
 {
+       auto_ref<CNDProvider> m_pProvider;
+       auto_ref<IWVDevice> m_pWvDevice;
+       auto_ref<IWVProtectionDomain> m_pWvPd;
+       DWORD                           m_MaxInlineSend;
+
+protected:
+       UINT64                          m_DeviceGuid;
+
+private:
+       CNDAdapter(CNDProvider& provider);
+       ~CNDAdapter(){};
+       HRESULT Init(UINT64 adapterId);
+
 public:
+       static HRESULT CreateInstance(CNDProvider& provider, UINT64 adapterId, VOID** ppAdapter);
+
+       IWVProvider* Prov(){ return m_pProvider->Prov(); }
+       IWVDevice* Dev(){ return m_pWvDevice.get(); }
+       IWVProtectionDomain* Pd(){ return m_pWvPd.get(); }
+       DWORD MaxInlineSend(){ return m_MaxInlineSend; }
+
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
@@ -48,67 +68,33 @@ public:
        // INDAdapter methods
        STDMETHODIMP_(HANDLE) GetFileHandle();
        STDMETHODIMP Query(ND_ADAPTER_INFO* pInfo, SIZE_T* pcbInfo);
-       STDMETHODIMP QueryAddressList(SOCKET_ADDRESS_LIST* pAddressList, SIZE_T* pcbAddressList);
-       STDMETHODIMP CreateCompletionQueue(DWORD queueDepth, GROUP_AFFINITY* pAffinity,
-                                                                          INDCompletionQueue** ppCompletionQueue);
-       STDMETHODIMP CreateMemoryRegion(INDMemoryRegion** ppMemoryRegion);
-       STDMETHODIMP CreateMemoryWindow(INDMemoryWindow** ppMemoryWindow);
-       STDMETHODIMP CreateSharedReceiveQueue(DWORD queueDepth, DWORD maxSGE,
-                                                                                 DWORD notifyThreshold, GROUP_AFFINITY* pAffinity,
-                                                                                 INDSharedReceiveQueue** ppSharedReceiveQueue);
-       STDMETHODIMP CreateQueuePair(INDCompletionQueue* pReceiveCompletionQueue,
-                                                                INDCompletionQueue* pInitiatorCompletionQueue, VOID* context,
+       STDMETHODIMP QueryAddressList(SOCKET_ADDRESS_LIST* pAddressList,
+                                                                 SIZE_T* pcbAddressList);
+       STDMETHODIMP CreateCompletionQueue(REFIID iid, DWORD queueDepth, USHORT group,
+                                                                          KAFFINITY affinity, VOID** ppCompletionQueue);
+       STDMETHODIMP CreateMemoryRegion(REFIID iid, VOID** ppMemoryRegion);
+       STDMETHODIMP CreateMemoryWindow(REFIID iid, VOID** ppMemoryWindow);
+       STDMETHODIMP CreateSharedReceiveQueue(REFIID iid, DWORD queueDepth, DWORD maxSge,
+                                                                                 DWORD notifyThreshold, USHORT group,
+                                                                                 KAFFINITY affinity, VOID** ppSharedReceiveQueue);
+       STDMETHODIMP CreateQueuePair(REFIID iid, IUnknown* pReceiveCompletionQueue,
+                                                                IUnknown* pInitiatorCompletionQueue, VOID* context,
                                                                 DWORD receiveQueueDepth, DWORD initiatorQueueDepth,
-                                                                DWORD maxReceiveRequestSGE, DWORD maxInitiatorRequestSGE,
-                                                                INDQueuePair** ppQueuePair);
-       STDMETHODIMP CreateQueuePairWithSRQ(INDCompletionQueue* pReceiveCompletionQueue,
-                                                                               INDCompletionQueue* pInitiatorCompletionQueue,
-                                                                               INDSharedReceiveQueue* pSharedReceiveQueue, VOID* context,
-                                                                               DWORD initiatorQueueDepth, DWORD maxInitiatorRequestSGE,
-                                                                               INDQueuePair** ppQueuePair);
-       STDMETHODIMP CreateSharedEndpoint(INDSharedEndpoint** ppSharedEndpoint);
-       STDMETHODIMP CreateConnector(INDConnector** ppConnector);
-       STDMETHODIMP CreateListen(INDListen** ppListen);
-
-       CNDAdapter(CNDProvider *pProvider);
-       ~CNDAdapter();
-       void Delete() {delete this;}
-       static STDMETHODIMP
-       CreateInstance(CNDProvider *pProvider, UINT64 adapterId, INDAdapter** ppAdapter)
-       {
-               HRESULT hr;
-               CNDAdapter *adapter;
-
-               adapter = new CNDAdapter(pProvider);
-               if (adapter == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err1;
-               }
-
-               hr = adapter->Init(adapterId);
-               if (FAILED(hr)) {
-                       goto err2;
-               }
-
-               *ppAdapter = adapter;
-               return ND_SUCCESS;
-
-       err2:
-               adapter->Release();
-       err1:
-               *ppAdapter = NULL;
-               return hr;
-       }
+                                                                DWORD maxReceiveRequestSge, DWORD maxInitiatorRequestSge,
+                                                                VOID** ppQueuePair);
+       STDMETHODIMP CreateQueuePairWithSrq(REFIID iid, IUnknown* pReceiveCompletionQueue,
+                                                                               IUnknown* pInitiatorCompletionQueue,
+                                                                               IUnknown* pSharedReceiveQueue, VOID* context,
+                                                                               DWORD initiatorQueueDepth,
+                                                                               DWORD maxInitiatorRequestSge, VOID** ppQueuePair);
+       STDMETHODIMP CreateSharedEndpoint(REFIID iid, VOID** ppSharedEndpoint);
+       STDMETHODIMP CreateConnector(REFIID iid, VOID** ppConnector);
+       STDMETHODIMP CreateListen(REFIID iid, VOID** ppListen);

-       CNDProvider                     *m_pProvider;
-       IWVDevice                       *m_pWvDevice;
-       IWVProtectionDomain     *m_pWvPd;
-       DWORD                           m_MaxInlineSend;
+};

-protected:
-       UINT64                          m_DeviceGuid;

-       STDMETHODIMP            Init(UINT64 adapterId);
-};
+} // namespace NetworkDirect
+} // namespace WinVerbs

 #endif // _ND_ADAPTER_H_
Index: user/nd_mw.h
===================================================================
--- user/nd_mw.h        (revision 2848)
+++ user/nd_mw.h        (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,59 +33,84 @@
 #ifndef _ND_MW_H_
 #define _ND_MW_H_

-#include <initguid.h>
-#include <ndspi.h>
-#include "nd_base.h"
-#include "nd_adapter.h"

-class CNDMemoryRegion : public INDMemoryRegion, public CNDBase
+namespace WinVerbs {
+namespace NetworkDirect {
+
+// {4F397DAE-11A9-4499-85CE-A9EBC608B99A}
+DEFINE_GUID(IID_NDoWVMr,
+0x4f397dae, 0x11a9, 0x4499, 0x85, 0xce, 0xa9, 0xeb, 0xc6, 0x8, 0xb9, 0x9a);
+
+class CNDMemoryRegion : public INDMemoryRegion, private CNDBase
 {
+       auto_ref<CNDAdapter> m_pAdapter;
+       WV_MEMORY_KEYS           m_Keys;
+       VOID* volatile           m_pOv;
+
+private:
+       CNDMemoryRegion(CNDAdapter& adapter);
+       ~CNDMemoryRegion(){};
+
 public:
+       static STDMETHODIMP
+       CreateInstance(CNDAdapter& adapter, VOID** ppMemoryRegion)
+       {
+               auto_ref<CNDMemoryRegion> mr(new CNDMemoryRegion(adapter));
+               if (mr.get() == NULL) {
+                       return ND_NO_MEMORY;
+               }
+
+               *ppMemoryRegion = mr.detach();
+               return ND_SUCCESS;
+       }
+
+       static DWORD ConvertAccessFlags(DWORD Flags);
+
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
        STDMETHODIMP_(ULONG) Release();

+       // INDOverlapped methods
+       STDMETHODIMP CancelOverlappedRequests();
+       STDMETHODIMP GetOverlappedResult(OVERLAPPED *pOverlapped, BOOL bWait);
+
        // INDMemoryRegion methods
        STDMETHODIMP Register(const VOID* pBuffer, SIZE_T cbBuffer, DWORD flags,
                                                  OVERLAPPED* pOverlapped);
-    STDMETHODIMP Deregister(OVERLAPPED* pOverlapped);
+       STDMETHODIMP Deregister(OVERLAPPED* pOverlapped);
        STDMETHODIMP_(UINT32) GetLocalToken();
        STDMETHODIMP_(UINT32) GetRemoteToken();
+};

-       CNDMemoryRegion(CNDAdapter *m_pAdapter);
-       ~CNDMemoryRegion();
-       void Delete() {delete this;}
+// {51662CD3-3CA2-44EF-9313-CA7C56833458}
+DEFINE_GUID(IID_NDoWVMw,
+0x51662cd3, 0x3ca2, 0x44ef, 0x93, 0x13, 0xca, 0x7c, 0x56, 0x83, 0x34, 0x58);
+
+class CNDMemoryWindow : public INDMemoryWindow, private CNDBase
+{
+       auto_ref<CNDMemoryRegion>       m_pMr;
+       auto_ref<CNDAdapter>            m_pAdapter;
+
+private:
+       CNDMemoryWindow(CNDAdapter& adapter);
+       ~CNDMemoryWindow(){};
+
+public:
        static STDMETHODIMP
-       CreateInstance(CNDAdapter *pAdapter, INDMemoryRegion** ppMemoryRegion)
+       CreateInstance(CNDAdapter& adapter, VOID** ppMemoryWindow)
        {
-               HRESULT hr;
-               CNDMemoryRegion *mr;
-
-               mr = new CNDMemoryRegion(pAdapter);
-               if (mr == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err;
+               auto_ref<CNDMemoryWindow> mw(new CNDMemoryWindow(adapter));
+               if (mw.get() == NULL) {
+                       return ND_NO_MEMORY;
                }

-               *ppMemoryRegion = mr;
+               *ppMemoryWindow = mw.detach();
                return ND_SUCCESS;
-
-       err:
-               *ppMemoryRegion = NULL;
-               return hr;
        }

-       WV_MEMORY_KEYS          m_Keys;
-
-protected:
-       CNDAdapter                      *m_pAdapter;
-};
-
+       void SetMr( CNDMemoryRegion* pMr ){ m_pMr = pMr; }

-class CNDMemoryWindow : public INDMemoryWindow, public CNDBase
-{
-public:
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
@@ -92,36 +118,9 @@ public:

        // INDMemoryWindow methods
        STDMETHODIMP_(UINT32) GetRemoteToken();
-
-       CNDMemoryWindow(CNDAdapter *m_pAdapter);
-       ~CNDMemoryWindow();
-       void Delete() {delete this;}
-       static STDMETHODIMP
-       CreateInstance(CNDAdapter *pAdapter, INDMemoryWindow** ppMemoryWindow)
-       {
-               HRESULT hr;
-               CNDMemoryWindow *mw;
-
-               mw = new CNDMemoryWindow(pAdapter);
-               if (mw == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err;
-               }
-
-               *ppMemoryWindow = mw;
-               return ND_SUCCESS;
-
-       err:
-               *ppMemoryWindow = NULL;
-               return hr;
-       }
-
-       CNDMemoryRegion         *m_pMr;
-
-protected:
-       CNDAdapter                      *m_pAdapter;
 };

-DWORD ConvertAccessFlags(DWORD Flags);
+} // namespace NetworkDirect
+} // namespace WinVerbs

 #endif // _ND_MW_H_
Index: user/precomp.h
===================================================================
--- user/precomp.h      (revision 0)
+++ user/precomp.h      (revision 0)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010 Microsoft 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 AND
+ * 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
+
+#include <ws2spi.h>
+#include <Windows.h>
+#include <tchar.h>
+#include <stdlib.h>
+#include <InitGuid.h>
+#include <ndspi.h>
+#include <rdma\winverbs.h>
Index: user/nd_connect.cpp
===================================================================
--- user/nd_connect.cpp (revision 2848)
+++ user/nd_connect.cpp (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,18 +28,28 @@
  * SOFTWARE.
  */

-#include "nd_connect.h"
+
+#include "precomp.h"
+#include "nd_base.h"
+#include "nd_provider.h"
+#include "nd_adapter.h"
 #include "nd_ep.h"
+#include "nd_cq.h"
+#include "nd_srq.h"
 #include "nd_qp.h"
 #include <iba/ibat.h>
+#include <InitGuid.h>
+#include "nd_connect.h"


-CNDConnector::CNDConnector(CNDAdapter *pAdapter)
+namespace WinVerbs {
+namespace NetworkDirect {
+
+CNDConnector::CNDConnector(CNDAdapter& adapter) :
+       m_pAdapter(&adapter),
+       m_pWvConnEp(NULL),
+       m_Connects(0)
 {
-       pAdapter->AddRef();
-       m_pAdapter = pAdapter;
-       m_pWvConnEp = NULL;
-       m_Connects = 0;
 }

 STDMETHODIMP CNDConnector::
@@ -47,27 +58,15 @@ Init(void)
        IWVConnectEndpoint *ep;
        HRESULT hr;

-       hr = m_pAdapter->m_pProvider->m_pWvProvider->CreateConnectEndpoint(&ep);
+       hr = m_pAdapter->Prov()->CreateConnectEndpoint(&ep);
        if (FAILED(hr)) {
                return NDConvertWVStatus(hr);
        }

-       if (m_pWvConnEp != NULL) {
-               m_pWvConnEp->Release();
-       }
-
        m_pWvConnEp = ep;
        return ND_SUCCESS;
 }

-CNDConnector::~CNDConnector()
-{
-       if (m_pWvConnEp != NULL) {
-               m_pWvConnEp->Release();
-       }
-       m_pAdapter->Release();
-}
-
 STDMETHODIMP CNDConnector::
 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
 {
@@ -112,14 +111,13 @@ GetOverlappedResult(OVERLAPPED *pOverlap
        return NDConvertWVStatus(hr);
 }

-STDMETHODIMP CNDConnector::
-ConnectQp(INDQueuePair* pQueuePair, BOOL SharedAddress,
-                 const struct sockaddr* pSrcAddress, SIZE_T cbSrcAddress,
-                 const struct sockaddr* pDestAddress, SIZE_T cbDestAddress,
+HRESULT CNDConnector::
+ConnectQp(CNDQueuePair& queuePair, BOOL SharedAddress,
+                 const struct sockaddr* pSrcAddress, SIZE_T,
+                 const struct sockaddr* pDestAddress, SIZE_T,
                  DWORD inboundReadLimit, DWORD outboundReadLimit,
                  const VOID* pPrivateData, DWORD cbPrivateData, OVERLAPPED* pOverlapped)
 {
-       CNDQueuePair *qp = (CNDQueuePair *) pQueuePair;
        WV_CONNECT_PARAM attr;
        IBAT_PATH_BLOB path;
        HRESULT hr;
@@ -153,41 +151,56 @@ ConnectQp(INDQueuePair* pQueuePair, BOOL
                goto out;
        }

-       RtlZeroMemory(&attr, sizeof attr);
-       if ((attr.DataLength = cbPrivateData)) {
-               RtlCopyMemory(attr.Data, pPrivateData, cbPrivateData);
+       ::RtlZeroMemory(&attr, sizeof attr);
+       if ((attr.DataLength = cbPrivateData) > 0) {
+               ::RtlCopyMemory(attr.Data, pPrivateData, cbPrivateData);
        }
        attr.ResponderResources = inboundReadLimit;
        attr.InitiatorDepth = outboundReadLimit;
        attr.RetryCount = 7;

-       hr = m_pWvConnEp->Connect(qp->m_pWvQp, pDestAddress, &attr, pOverlapped);
+       hr = m_pWvConnEp->Connect(queuePair.Qp(), pDestAddress, &attr, pOverlapped);
 out:
        return NDConvertWVStatus(hr);
 }

 STDMETHODIMP CNDConnector::
-Connect(INDQueuePair* pQueuePair,
+Connect(IUnknown* pQueuePair,
                const struct sockaddr* pSrcAddress, SIZE_T cbSrcAddress,
                const struct sockaddr* pDestAddress, SIZE_T cbDestAddress,
                DWORD inboundReadLimit, DWORD outboundReadLimit,
                const VOID* pPrivateData, DWORD cbPrivateData, OVERLAPPED* pOverlapped)
 {
-       return ConnectQp(pQueuePair, FALSE, pSrcAddress, cbSrcAddress,
+       auto_ref<CNDQueuePair> qp(NULL);
+       HRESULT hr = pQueuePair->QueryInterface(IID_NDoWVQp, qp.ppvObj());
+       if( FAILED(hr) ){
+               return ND_INVALID_PARAMETER_1;
+       }
+       return ConnectQp(*qp.get(), FALSE, pSrcAddress, cbSrcAddress,
                                         pDestAddress, cbDestAddress, inboundReadLimit,
                                         outboundReadLimit, pPrivateData, cbPrivateData, pOverlapped);
 }

 STDMETHODIMP CNDConnector::
-ConnectSharedEndpoint(INDQueuePair* pQueuePair, INDSharedEndpoint* pSharedEndpoint,
+ConnectSharedEndpoint(IUnknown* pQueuePair, IUnknown* pSharedEndpoint,
                                          const struct sockaddr* pDestAddress, SIZE_T cbDestAddress,
                                          DWORD inboundReadLimit, DWORD outboundReadLimit,
                                          const VOID* pPrivateData, DWORD cbPrivateData,
                                          OVERLAPPED* pOverlapped)
 {
-       CNDSharedEndpoint *sep = (CNDSharedEndpoint *) pSharedEndpoint;
+       auto_ref<CNDQueuePair> qp(NULL);
+       HRESULT hr = pQueuePair->QueryInterface( IID_NDoWVQp, qp.ppvObj() );
+       if( FAILED(hr) ){
+               return ND_INVALID_PARAMETER_1;
+       }

-       return ConnectQp(pQueuePair, TRUE, (SOCKADDR *) &sep->m_Address, sep->m_AddressSize,
+       auto_ref<CNDSharedEndpoint> sep(NULL);
+       hr = pSharedEndpoint->QueryInterface( IID_NDoWVSep, sep.ppvObj() );
+       if( FAILED(hr) ){
+               return ND_INVALID_PARAMETER_2;
+       }
+
+       return ConnectQp(*qp.get(), TRUE, sep->Addr(), sep->AddrLen(),
                                         pDestAddress, cbDestAddress, inboundReadLimit,
                                         outboundReadLimit, pPrivateData, cbPrivateData, pOverlapped);
 }
@@ -198,27 +211,31 @@ CompleteConnect(OVERLAPPED* pOverlapped)
        WV_CONNECT_PARAM attr;
        HRESULT hr;

-       RtlZeroMemory(&attr, sizeof attr);
+       ::RtlZeroMemory(&attr, sizeof attr);
        hr = m_pWvConnEp->Accept(NULL, &attr, pOverlapped);
        return NDConvertWVStatus(hr);
 }

 STDMETHODIMP CNDConnector::
-Accept(INDQueuePair* pQueuePair, DWORD inboundReadLimit, DWORD outboundReadLimit,
+Accept(IUnknown* pQueuePair, DWORD inboundReadLimit, DWORD outboundReadLimit,
           const VOID* pPrivateData, DWORD cbPrivateData, OVERLAPPED* pOverlapped)
 {
-       CNDQueuePair *qp = (CNDQueuePair *) pQueuePair;
+       auto_ref<CNDQueuePair> qp(NULL);
+       HRESULT hr = pQueuePair->QueryInterface( IID_NDoWVQp, qp.ppvObj() );
+       if( FAILED(hr) ){
+               return ND_INVALID_PARAMETER_1;
+       }
+
        WV_CONNECT_PARAM attr;
-       HRESULT hr;

-       RtlZeroMemory(&attr, sizeof attr);
-       if ((attr.DataLength = cbPrivateData)) {
-               RtlCopyMemory(attr.Data, pPrivateData, cbPrivateData);
+       ::RtlZeroMemory(&attr, sizeof attr);
+       if ((attr.DataLength = cbPrivateData) > 0) {
+               ::RtlCopyMemory(attr.Data, pPrivateData, cbPrivateData);
        }
        attr.ResponderResources = inboundReadLimit;
        attr.InitiatorDepth = outboundReadLimit;

-       hr = m_pWvConnEp->Accept(qp->m_pWvQp, &attr, pOverlapped);
+       hr = m_pWvConnEp->Accept(qp->Qp(), &attr, pOverlapped);
        return NDConvertWVStatus(hr);
 }

@@ -250,13 +267,13 @@ GetConnectionData(DWORD* pInboundReadLim
                *pOutboundReadLimit = (DWORD) attr.Param.InitiatorDepth;
        }
        if (pcbPrivateData) {
-               if (*pcbPrivateData < ND_PRIVATE_DATA_SIZE) {
+               if (*pcbPrivateData < RTL_FIELD_SIZE(WV_CONNECT_PARAM, Data)) {
                        hr = ND_BUFFER_OVERFLOW;
                }

-               RtlCopyMemory(pPrivateData, attr.Param.Data,
-                                         min(*pcbPrivateData, ND_PRIVATE_DATA_SIZE));
-               *pcbPrivateData = ND_PRIVATE_DATA_SIZE;
+               ::RtlCopyMemory(pPrivateData, attr.Param.Data,
+                                         min(*pcbPrivateData, RTL_FIELD_SIZE(WV_CONNECT_PARAM, Data)));
+               *pcbPrivateData = RTL_FIELD_SIZE(WV_CONNECT_PARAM, Data);
        }

        return hr;
@@ -281,7 +298,7 @@ GetLocalAddress(struct sockaddr* pAddres

        size = GetAddressSize(&attr.LocalAddress);
        if (*pcbAddress >= size) {
-               RtlCopyMemory(pAddress, &attr.LocalAddress, size);
+               ::RtlCopyMemory(pAddress, &attr.LocalAddress, size);
        } else {
                hr = ND_BUFFER_OVERFLOW;
        }
@@ -304,7 +321,7 @@ GetPeerAddress(struct sockaddr* pAddress

        size = GetAddressSize(&attr.PeerAddress);
        if (*pcbAddress >= size) {
-               RtlCopyMemory(pAddress, &attr.PeerAddress, size);
+               ::RtlCopyMemory(pAddress, &attr.PeerAddress, size);
        } else {
                hr = ND_BUFFER_OVERFLOW;
        }
@@ -330,3 +347,7 @@ Disconnect(OVERLAPPED* pOverlapped)
        hr = m_pWvConnEp->Disconnect(pOverlapped);
        return NDConvertWVStatus(hr);
 }
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
+
Index: user/nd_provider.cpp
===================================================================
--- user/nd_provider.cpp        (revision 2848)
+++ user/nd_provider.cpp        (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,22 +28,40 @@
  * SOFTWARE.
  */

+#include "precomp.h"
+#include "nd_base.h"
 #include "nd_provider.h"
 #include "nd_adapter.h"
-#include <ws2tcpip.h>

-CNDProvider::CNDProvider()
+
+namespace WinVerbs {
+namespace NetworkDirect {
+
+CNDProvider::CNDProvider() :
+       m_pWvProvider( NULL )
 {
-       WvGetObject(IID_IWVProvider, (LPVOID *) &m_pWvProvider);
 }

-CNDProvider::~CNDProvider()
+
+HRESULT
+CNDProvider::Init()
 {
-       if (m_pWvProvider) {
-               m_pWvProvider->Release();
+       HRESULT hr = WvGetObject(IID_IWVProvider, (LPVOID *)m_pWvProvider.ref());
+       if( FAILED( hr ) ){
+               return hr;
+       }
+
+       if( !::SetFileCompletionNotificationModes(
+               m_pWvProvider->GetFileHandle(),
+               FILE_SKIP_COMPLETION_PORT_ON_SUCCESS | FILE_SKIP_SET_EVENT_ON_HANDLE ) )
+       {
+               return HRESULT_FROM_WIN32( GetLastError() );
        }
+
+       return ND_SUCCESS;
 }

+
 STDMETHODIMP CNDProvider::
 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
 {
@@ -51,8 +70,8 @@ QueryInterface(REFIID riid, LPVOID FAR*
                return E_NOINTERFACE;
        }

-       *ppvObj = this;
        AddRef();
+       *ppvObj = this;
        return ND_SUCCESS;
 }

@@ -68,30 +87,30 @@ Release(void)
        return CNDBase::Release();
 }

-STDMETHODIMP CNDProvider::
+HRESULT CNDProvider::
 QueryAdapterAddressList(SOCKET_ADDRESS_LIST* pAddressList,
                                                SIZE_T* pcbAddressList, UINT64 adapterId)
 {
        WV_DEVICE_ADDRESS devaddr;
        struct addrinfo *res, *ai;
-       HRESULT hr;
        int cnt = 0;
        size_t addrlen = 0, size;
        UINT8 *offset;

-       if (m_pWvProvider == NULL) {
-               return ND_INSUFFICIENT_RESOURCES;
-       }
-
-       hr = getaddrinfo("..localmachine", NULL, NULL, &res);
-       if (hr) {
-               goto out;
+       HRESULT hr = HRESULT_FROM_WIN32(
+               getaddrinfo("..localmachine", NULL, NULL, &res)
+               );
+       if (FAILED(hr)) {
+               return hr;
        }

-       for (ai = res; ai; ai = ai->ai_next) {
+       for (ai = res; ai; ai = ai->ai_next)
+       {
+               // We overwrite the flags so that we can identify which addresses to copy.
                ai->ai_flags = m_pWvProvider->TranslateAddress(ai->ai_addr, &devaddr);
                if (SUCCEEDED(ai->ai_flags) &&
-                       ((adapterId == 0) || (adapterId == devaddr.DeviceGuid))) {
+                       ((adapterId == 0) || (adapterId == devaddr.DeviceGuid)))
+               {
                        cnt++;
                        addrlen += ai->ai_addrlen;
                }
@@ -110,19 +129,19 @@ QueryAdapterAddressList(SOCKET_ADDRESS_L
        }

        pAddressList->iAddressCount = cnt;
-       offset = (UINT8 *) pAddressList + size;
+       offset = reinterpret_cast<UINT8 *>(pAddressList) + size;
        for (cnt = 0, ai = res; ai; ai = ai->ai_next) {
+               // Copy only addresses that succeeded TranslateAddress.
                if (SUCCEEDED(ai->ai_flags)) {
-                       pAddressList->Address[cnt].iSockaddrLength = ai->ai_addrlen;
-                       pAddressList->Address[cnt].lpSockaddr = (LPSOCKADDR) offset;
-                       RtlCopyMemory(offset, ai->ai_addr, ai->ai_addrlen);
+                       pAddressList->Address[cnt].iSockaddrLength = static_cast<INT>(ai->ai_addrlen);
+                       pAddressList->Address[cnt].lpSockaddr = reinterpret_cast<LPSOCKADDR>(offset);
+                       ::RtlCopyMemory(offset, ai->ai_addr, ai->ai_addrlen);
                        offset += ai->ai_addrlen;
                }
        }

 free:
        freeaddrinfo(res);
-out:
        return NDConvertWVStatus(hr);
 }

@@ -133,12 +152,11 @@ QueryAddressList(SOCKET_ADDRESS_LIST* pA
 }

 STDMETHODIMP CNDProvider::
-ResolveAddress(const struct sockaddr* pAddress, SIZE_T cbAddress, UINT64* pAdapterId)
+ResolveAddress(const struct sockaddr* pAddress, SIZE_T, UINT64* pAdapterId)
 {
        WV_DEVICE_ADDRESS devaddr;
-       HRESULT hr;

-       hr = m_pWvProvider->TranslateAddress(pAddress, &devaddr);
+       HRESULT hr = m_pWvProvider->TranslateAddress(pAddress, &devaddr);
        if (FAILED(hr)) {
                return NDConvertWVStatus(hr);
        }
@@ -148,64 +166,15 @@ ResolveAddress(const struct sockaddr* pA
 }

 STDMETHODIMP CNDProvider::
-OpenAdapter(UINT64 adapterId, INDAdapter** ppAdapter)
-{
-       return CNDAdapter::CreateInstance(this, adapterId, ppAdapter);
-}
-
-
-//-------------------------
-// CNDClassFactory routines
-//-------------------------
-
-STDMETHODIMP CNDClassFactory::
-QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
+OpenAdapter( REFIID iid, UINT64 adapterId, VOID** ppAdapter)
 {
-       if (riid != IID_IUnknown && riid != IID_IClassFactory) {
-               *ppvObj = NULL;
+       if( iid != IID_INDAdapter ){
                return E_NOINTERFACE;
        }

-       *ppvObj = this;
-       AddRef();
-       return ND_SUCCESS;
-}
-
-STDMETHODIMP_(ULONG) CNDClassFactory::
-AddRef(void)
-{
-       return CNDBase::AddRef();
-}
-
-STDMETHODIMP_(ULONG) CNDClassFactory::
-Release(void)
-{
-       return CNDBase::Release();
+       return CNDAdapter::CreateInstance( *this, adapterId, ppAdapter);
 }

-STDMETHODIMP CNDClassFactory::
-CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppObject)
-{
-       if (pUnkOuter != NULL) {
-               return CLASS_E_NOAGGREGATION;
-       }
-
-       if (riid != IID_INDProvider) {
-               *ppObject = NULL;
-               return E_NOINTERFACE;
-       }
-
-       *ppObject = new CNDProvider();
-       if (*ppObject == NULL) {
-               return E_OUTOFMEMORY;
-       }
-
-       return S_OK;
-}
+} // namespace NetworkDirect
+} // namespace WinVerbs

-STDMETHODIMP CNDClassFactory::
-LockServer(BOOL fLock)
-{
-       UNREFERENCED_PARAMETER(fLock);
-       return S_OK;
-}
Index: user/nd_listen.cpp
===================================================================
--- user/nd_listen.cpp  (revision 2848)
+++ user/nd_listen.cpp  (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,24 +28,24 @@
  * SOFTWARE.
  */

-#include "nd_listen.h"
+#include "precomp.h"
+#include "nd_base.h"
+#include "nd_provider.h"
 #include "nd_adapter.h"
+#include "nd_cq.h"
+#include "nd_srq.h"
+#include "nd_qp.h"
 #include "nd_connect.h"
+#include "nd_listen.h"


-CNDListen::CNDListen(CNDAdapter *pAdapter)
-{
-       pAdapter->AddRef();
-       m_pAdapter = pAdapter;
-       m_pWvConnEp = NULL;
-}
+namespace WinVerbs {
+namespace NetworkDirect {

-CNDListen::~CNDListen()
+CNDListen::CNDListen(CNDAdapter& adapter) :
+       m_pAdapter(&adapter),
+       m_pWvConnEp(NULL)
 {
-       if (m_pWvConnEp != NULL) {
-               m_pWvConnEp->Release();
-       }
-       m_pAdapter->Release();
 }

 STDMETHODIMP CNDListen::
@@ -92,32 +93,27 @@ GetOverlappedResult(OVERLAPPED *pOverlap
 }

 STDMETHODIMP CNDListen::
-Listen(const struct sockaddr* pAddress, SIZE_T cbAddress, SIZE_T backlog)
+Listen(const struct sockaddr* pAddress, SIZE_T, SIZE_T backlog)
 {
-       WV_SOCKADDR addr;
        HRESULT hr;
-
-       hr = m_pAdapter->m_pProvider->m_pWvProvider->CreateConnectEndpoint(&m_pWvConnEp);
+       auto_ref<IWVConnectEndpoint> ep(NULL);
+       hr = m_pAdapter->Prov()->CreateConnectEndpoint(ep.ref());
+       NDConvertWVStatus(hr);
        if (FAILED(hr)) {
-               return NDConvertWVStatus(hr);
+               return hr;
        }

-       hr = m_pWvConnEp->BindAddress((SOCKADDR *) pAddress);
+       hr = NDConvertWVStatus(ep->BindAddress(const_cast<SOCKADDR *>(pAddress)));
        if (FAILED(hr)) {
-               goto err;
+               return hr;
        }

-       hr = m_pWvConnEp->Listen(backlog);
-       if (FAILED(hr)) {
-               goto err;
+       hr = NDConvertWVStatus(ep->Listen(backlog));
+       if (SUCCEEDED(hr)) {
+               m_pWvConnEp = ep;
        }

-       return ND_SUCCESS;
-
-err:
-       m_pWvConnEp->Release();
-       m_pWvConnEp = NULL;
-       return NDConvertWVStatus(hr);
+       return hr;
 }

 STDMETHODIMP CNDListen::
@@ -134,7 +130,7 @@ GetLocalAddress(struct sockaddr* pAddres

        size = GetAddressSize(&attr.LocalAddress);
        if (*pcbAddress >= size) {
-               RtlCopyMemory(pAddress, &attr.LocalAddress.Sa, size);
+               ::RtlCopyMemory(pAddress, &attr.LocalAddress.Sa, size);
        } else {
                hr = ND_BUFFER_OVERFLOW;
        }
@@ -144,11 +140,17 @@ GetLocalAddress(struct sockaddr* pAddres
 }

 STDMETHODIMP CNDListen::
-GetConnectionRequest(INDConnector* pConnector, OVERLAPPED* pOverlapped)
+GetConnectionRequest(IUnknown* pConnector, OVERLAPPED* pOverlapped)
 {
-       CNDConnector *conn = (CNDConnector *) pConnector;
-       HRESULT hr;
+       CNDConnector *conn;
+       HRESULT hr = pConnector->QueryInterface(IID_NDoWVConn, reinterpret_cast<void**>(&conn));
+       if(FAILED(hr)){
+               return ND_INVALID_PARAMETER_1;
+       }

-       hr = m_pWvConnEp->GetRequest(conn->m_pWvConnEp, pOverlapped);
+       hr = m_pWvConnEp->GetRequest(conn->Ep(), pOverlapped);
        return NDConvertWVStatus(hr);
 }
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
Index: user/nd_connect.h
===================================================================
--- user/nd_connect.h   (revision 2848)
+++ user/nd_connect.h   (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,18 +33,49 @@
 #ifndef _ND_CONNECTOR_H_
 #define _ND_CONNECTOR_H_

-#include <initguid.h>
-#include <ndspi.h>
-#include "nd_base.h"
-#include "nd_adapter.h"
-

-#define ND_PRIVATE_DATA_SIZE   56
+namespace WinVerbs {
+namespace NetworkDirect {

+// {72A77274-FA10-4124-A844-7A7E12D6370A}
+DEFINE_GUID(IID_NDoWVConn,
+0x72a77274, 0xfa10, 0x4124, 0xa8, 0x44, 0x7a, 0x7e, 0x12, 0xd6, 0x37, 0xa);

-class CNDConnector : public INDConnector, public CNDBase
+class CNDConnector : public INDConnector, private CNDBase
 {
+       auto_ref<IWVConnectEndpoint>    m_pWvConnEp;
+       auto_ref<CNDAdapter>                    m_pAdapter;
+       int                                                             m_Connects;
+
+private:
+       CNDConnector(CNDAdapter& adapter);
+       HRESULT Init();
+       HRESULT ConnectQp(CNDQueuePair& queuePair, BOOL SharedAddress,
+                                         const struct sockaddr* pSrcAddress, SIZE_T cbSrcAddress,
+                                         const struct sockaddr* pDestAddress, SIZE_T cbDestAddress,
+                                         DWORD inboundReadLimit, DWORD outboundReadLimit,
+                                         const VOID* pPrivateData, DWORD cbPrivateData,
+                                         OVERLAPPED* pOverlapped);
+
 public:
+       static STDMETHODIMP
+       CreateInstance(CNDAdapter& adapter, VOID** ppConnector)
+       {
+               auto_ref<CNDConnector> conn(new CNDConnector(adapter));
+               if (conn.get() == NULL) {
+                       return ND_NO_MEMORY;
+               }
+
+               HRESULT hr = conn->Init();
+               if (SUCCEEDED(hr)) {
+                       *ppConnector = conn.detach();
+               }
+
+               return hr;
+       }
+
+       IWVConnectEndpoint* Ep(){ return m_pWvConnEp.get(); }
+
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
@@ -54,18 +86,18 @@ public:
        STDMETHODIMP GetOverlappedResult(OVERLAPPED *pOverlapped, BOOL bWait);

        // INDConnector methods
-       STDMETHODIMP Connect(INDQueuePair* pQueuePair,
+       STDMETHODIMP Connect(IUnknown* pQueuePair,
                                                 const struct sockaddr* pSrcAddress, SIZE_T cbSrcAddress,
                                                 const struct sockaddr* pDestAddress, SIZE_T cbDestAddress,
                                                 DWORD inboundReadLimit, DWORD outboundReadLimit,
                                                 const VOID* pPrivateData, DWORD cbPrivateData, OVERLAPPED* pOverlapped);
-       STDMETHODIMP ConnectSharedEndpoint(INDQueuePair* pQueuePair, INDSharedEndpoint* pSharedEndpoint,
+       STDMETHODIMP ConnectSharedEndpoint(IUnknown* pQueuePair, IUnknown* pSharedEndpoint,
                                                                           const struct sockaddr* pDestAddress, SIZE_T cbDestAddress,
                                                                           DWORD inboundReadLimit, DWORD outboundReadLimit,
                                                                           const VOID* pPrivateData, DWORD cbPrivateData,
                                                                           OVERLAPPED* pOverlapped);
        STDMETHODIMP CompleteConnect(OVERLAPPED* pOverlapped);
-       STDMETHODIMP Accept(INDQueuePair* pQueuePair, DWORD inboundReadLimit, DWORD outboundReadLimit,
+       STDMETHODIMP Accept(IUnknown* pQueuePair, DWORD inboundReadLimit, DWORD outboundReadLimit,
                                                const VOID* pPrivateData, DWORD cbPrivateData, OVERLAPPED* pOverlapped);
        STDMETHODIMP Reject(const VOID* pPrivateData, DWORD cbPrivateData);
        STDMETHODIMP GetConnectionData(DWORD* pInboundReadLimit, DWORD* pOutboundReadLimit,
@@ -74,51 +106,11 @@ public:
        STDMETHODIMP GetPeerAddress(struct sockaddr* pAddress, SIZE_T* pcbAddress);
        STDMETHODIMP NotifyDisconnect(OVERLAPPED* pOverlapped);
        STDMETHODIMP Disconnect(OVERLAPPED* pOverlapped);
-
-       CNDConnector(CNDAdapter *pAdapter);
-       ~CNDConnector();
-       void Delete() {delete this;}
-       static STDMETHODIMP
-       CreateInstance(CNDAdapter *pAdapter, INDConnector** ppConnector)
-       {
-               HRESULT hr;
-               CNDConnector *conn;
-
-               conn = new CNDConnector(pAdapter);
-               if (conn == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err1;
-               }
-
-               hr = conn->Init();
-               if (FAILED(hr)) {
-                       goto err2;
-               }
-
-               *ppConnector = conn;
-               return ND_SUCCESS;
-
-       err2:
-               conn->Release();
-       err1:
-               *ppConnector = NULL;
-               return hr;
-       }
-
-       IWVConnectEndpoint      *m_pWvConnEp;
-       CNDAdapter                      *m_pAdapter;
-
-protected:
-       STDMETHODIMP            Init();
-       STDMETHODIMP            ConnectQp(INDQueuePair* pQueuePair, BOOL SharedAddress,
-                                                                 const struct sockaddr* pSrcAddress, SIZE_T cbSrcAddress,
-                                                                 const struct sockaddr* pDestAddress, SIZE_T cbDestAddress,
-                                                                 DWORD inboundReadLimit, DWORD outboundReadLimit,
-                                                                 const VOID* pPrivateData, DWORD cbPrivateData,
-                                                                 OVERLAPPED* pOverlapped);
-       int                                     m_Connects;
 };

 SIZE_T GetAddressSize(WV_SOCKADDR *addr);
+
+} // namespace NetworkDirect
+} // namespace WinVerbs

 #endif // _ND_CONNECTOR_H_
Index: user/nd_provider.h
===================================================================
--- user/nd_provider.h  (revision 2848)
+++ user/nd_provider.h  (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,50 +33,69 @@
 #ifndef _ND_PROVIDER_H_
 #define _ND_PROVIDER_H_

-#include <initguid.h>
-#include <ndspi.h>
-#include "nd_base.h"

-class CNDProvider : public INDProvider, public CNDBase
+namespace WinVerbs {
+namespace NetworkDirect {
+
+class CNDProvider : public INDProvider, private CNDBase
 {
+       auto_ref<IWVProvider> m_pWvProvider;
+
+private:
+       CNDProvider();
+       ~CNDProvider(){};
+
+       HRESULT Init();
+
 public:
-       // IUnknown methods
-       STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
-       STDMETHODIMP_(ULONG) AddRef();
-       STDMETHODIMP_(ULONG) Release();
+       static HRESULT CreateInstance( VOID** ppProvider )
+       {
+               auto_ref<CNDProvider> pProvider( new CNDProvider() );
+               if( pProvider.get() == NULL ){
+                       return E_OUTOFMEMORY;
+               }

-       // INDProvider methods
-       STDMETHODIMP QueryAddressList(SOCKET_ADDRESS_LIST* pAddressList,
-                                                                 SIZE_T* pcbAddressList);
-       STDMETHODIMP ResolveAddress(const struct sockaddr* pAddress,
-                                                               SIZE_T cbAddress, UINT64* pAdapterId);
-       STDMETHODIMP OpenAdapter(UINT64 adapterId, INDAdapter** ppAdapter);
+               HRESULT hr = pProvider->Init();
+               if( SUCCEEDED( hr ) ){
+                       *ppProvider = pProvider.detach();
+               }

-       CNDProvider();
-       ~CNDProvider();
-       void Delete() {delete this;}
+               return hr;
+       }

-       STDMETHODIMP QueryAdapterAddressList(SOCKET_ADDRESS_LIST* pAddressList,
-                                                                                SIZE_T* pcbAddressList, UINT64 adapterId);
-       IWVProvider *m_pWvProvider;
-};
+       IWVProvider* Prov(){ return m_pWvProvider.get(); }

+       HRESULT QueryAdapterAddressList(
+               SOCKET_ADDRESS_LIST* pAddressList,
+               SIZE_T* pcbAddressList,
+               UINT64 adapterId
+               );

-class CNDClassFactory : public IClassFactory, public CNDBase
-{
-public:
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
        STDMETHODIMP_(ULONG) Release();

-       // IClassFactory methods
-       STDMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppObject);
-       STDMETHODIMP LockServer(BOOL fLock);
+       // INDProvider methods
+       STDMETHODIMP QueryAddressList(
+               SOCKET_ADDRESS_LIST* pAddressList,
+               SIZE_T* pcbAddressList
+               );

-       CNDClassFactory() {};
-       ~CNDClassFactory() {};
-       void Delete() {delete this;}
+       STDMETHODIMP ResolveAddress(
+               const struct sockaddr* pAddress,
+               SIZE_T cbAddress,
+               UINT64* pAdapterId
+               );
+
+       STDMETHODIMP OpenAdapter(
+               REFIID iid,
+               UINT64 adapterId,
+               VOID** ppAdapter);
 };
+
+
+} // namespace NetworkDirect
+} // namespace WinVerbs

 #endif // _ND_PROVIDER_H_
Index: user/nd_listen.h
===================================================================
--- user/nd_listen.h    (revision 2848)
+++ user/nd_listen.h    (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,14 +33,31 @@
 #ifndef _ND_LISTEN_H_
 #define _ND_LISTEN_H_

-#include <initguid.h>
-#include <ndspi.h>
-#include "nd_base.h"
-#include "nd_adapter.h"

-class CNDListen : public INDListen, public CNDBase
+namespace WinVerbs {
+namespace NetworkDirect {
+
+class CNDListen : public INDListen, private CNDBase
 {
+       auto_ref<CNDAdapter>                    m_pAdapter;
+       auto_ref<IWVConnectEndpoint>    m_pWvConnEp;
+
+private:
+       CNDListen(CNDAdapter& adapter);
+
 public:
+       static STDMETHODIMP
+       CreateInstance(CNDAdapter& adapter, VOID** ppListen)
+       {
+               auto_ref<CNDListen> listener(new CNDListen(adapter));
+               if (listener.get() == NULL) {
+                       return ND_NO_MEMORY;
+               }
+
+               *ppListen = listener.detach();
+               return ND_SUCCESS;
+       }
+
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
@@ -52,36 +70,10 @@ public:
        // INDListen methods
        STDMETHODIMP Listen(const struct sockaddr* pAddress, SIZE_T cbAddress, SIZE_T backlog);
        STDMETHODIMP GetLocalAddress(struct sockaddr* pAddress, SIZE_T* pcbAddress);
-       STDMETHODIMP GetConnectionRequest(INDConnector* pConnector, OVERLAPPED* pOverlapped);
-
-       CNDListen(CNDAdapter *pAdapter);
-       ~CNDListen();
-       void Delete() {delete this;}
-       static STDMETHODIMP
-       CreateInstance(CNDAdapter *pAdapter, INDListen** ppListen)
-       {
-               HRESULT hr;
-               CNDListen *listener;
-
-               listener = new CNDListen(pAdapter);
-               if (listener == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err1;
-               }
-
-               *ppListen = listener;
-               return ND_SUCCESS;
-
-       err1:
-               *ppListen = NULL;
-               return hr;
-       }
-
-protected:
-       CNDAdapter                      *m_pAdapter;
-       IWVConnectEndpoint      *m_pWvConnEp;
-
-       STDMETHODIMP            Init();
+       STDMETHODIMP GetConnectionRequest(IUnknown* pConnector, OVERLAPPED* pOverlapped);
 };
+
+} // namespace NetworkDirect
+} // namespace WinVerbs

 #endif // _ND_LISTEN_H_
Index: user/nd_cq.cpp
===================================================================
--- user/nd_cq.cpp      (revision 2848)
+++ user/nd_cq.cpp      (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,36 +28,37 @@
  * SOFTWARE.
  */

+
+#include "precomp.h"
+#include "nd_base.h"
+#include "nd_provider.h"
+#include "nd_adapter.h"
+#include <InitGuid.h>
 #include "nd_cq.h"

-CNDCompletionQueue::CNDCompletionQueue(CNDAdapter *pAdapter)
+
+namespace WinVerbs {
+namespace NetworkDirect {
+
+CNDCompletionQueue::CNDCompletionQueue(CNDAdapter &adapter) :
+       m_pAdapter( &adapter ),
+       m_pWvCq( NULL )
 {
-       pAdapter->AddRef();
-       m_pAdapter = pAdapter;
-       m_pWvCq = NULL;
 }

 STDMETHODIMP CNDCompletionQueue::
 Init(DWORD queueDepth)
 {
-       HRESULT hr;
-
-       hr = m_pAdapter->m_pWvDevice->CreateCompletionQueue((SIZE_T *) &queueDepth, &m_pWvCq);
-       return NDConvertWVStatus(hr);
-}
-
-CNDCompletionQueue::~CNDCompletionQueue()
-{
-       if (m_pWvCq != NULL) {
-               m_pWvCq->Release();
-       }
-       m_pAdapter->Release();
+       SIZE_T qDepth = queueDepth;
+       return NDConvertWVStatus(
+               m_pAdapter->Dev()->CreateCompletionQueue(&qDepth, m_pWvCq.ref())
+               );
 }

 STDMETHODIMP CNDCompletionQueue::
 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
 {
-       if (riid != IID_IUnknown && riid != IID_INDCompletionQueue) {
+       if (riid != IID_IUnknown && riid != IID_INDCompletionQueue && riid != IID_NDoWVCq) {
                *ppvObj = NULL;
                return E_NOINTERFACE;
        }
@@ -91,28 +93,29 @@ STDMETHODIMP CNDCompletionQueue::
 GetOverlappedResult(OVERLAPPED *pOverlapped, BOOL bWait)
 {
        DWORD bytes;
-       HRESULT hr;
+       return NDConvertWVStatus( m_pWvCq->GetOverlappedResult(pOverlapped, &bytes, bWait) );
+}

-       hr = m_pWvCq->GetOverlappedResult(pOverlapped, &bytes, bWait);
-       return NDConvertWVStatus(hr);
+STDMETHODIMP CNDCompletionQueue::
+GetNotifyAffinity(USHORT*, KAFFINITY*)
+{
+       return ND_NOT_SUPPORTED;
 }

+C_ASSERT( ND_CQ_NOTIFY_ERRORS == WvCqError );
+C_ASSERT( ND_CQ_NOTIFY_ANY == WvCqNextCompletion );
+C_ASSERT( ND_CQ_NOTIFY_SOLICITED == WvCqSolicited );
+
 STDMETHODIMP CNDCompletionQueue::
 Resize(DWORD queueDepth)
 {
-       HRESULT hr;
-
-       hr = m_pWvCq->Resize((SIZE_T *) &queueDepth);
-       return NDConvertWVStatus(hr);
+       return NDConvertWVStatus(m_pWvCq->Resize((SIZE_T *) &queueDepth));
 }

 STDMETHODIMP CNDCompletionQueue::
 Notify(DWORD type, OVERLAPPED* pOverlapped)
 {
-       HRESULT hr;
-
-       hr = m_pWvCq->Notify((WV_CQ_NOTIFY_TYPE) type, pOverlapped);
-       return NDConvertWVStatus(hr);
+       return NDConvertWVStatus(m_pWvCq->Notify((WV_CQ_NOTIFY_TYPE) type, pOverlapped));
 }

 STDMETHODIMP_(HRESULT) CNDCompletionQueue::
@@ -124,10 +127,10 @@ ConvertStatus(WV_WC_STATUS Status)
        case WvWcFlushed:
                return ND_CANCELED;
        case WvWcLocalLengthError:
-               return ND_LOCAL_LENGTH;
+               return ND_DATA_OVERRUN;
        case WvWcRnrRetryError:
        case WvWcTimeoutRetryError:
-               return ND_TIMEOUT;
+               return ND_IO_TIMEOUT;
        case WvWcLocalAccessError:
        case WvWcLocalOpError:
        case WvWcLocalProtectionError:
@@ -167,3 +170,7 @@ GetResults(ND_RESULT results[], DWORD nR
        }
        return total;
 }
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
+
Index: user/nd_ep.cpp
===================================================================
--- user/nd_ep.cpp      (revision 2848)
+++ user/nd_ep.cpp      (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,20 +28,23 @@
  * SOFTWARE.
  */

-#include "nd_ep.h"
+
+#include "precomp.h"
+#include "nd_base.h"
+#include "nd_provider.h"
 #include "nd_adapter.h"
-#include <netinet/in.h>
+#include <InitGuid.h>
+#include "nd_ep.h"


-CNDSharedEndpoint::CNDSharedEndpoint(CNDAdapter *pAdapter)
-{
-       pAdapter->AddRef();
-       m_pAdapter = pAdapter;
-}
+namespace WinVerbs {
+namespace NetworkDirect {

-CNDSharedEndpoint::~CNDSharedEndpoint()
+CNDSharedEndpoint::CNDSharedEndpoint(CNDAdapter& adapter) :
+       m_pAdapter( &adapter ),
+       m_AddressSize( 0 )
 {
-       m_pAdapter->Release();
+       ::RtlZeroMemory( &m_Address, sizeof(m_Address) );
 }

 STDMETHODIMP CNDSharedEndpoint::
@@ -68,11 +72,36 @@ Release(void)
        return CNDBase::Release();
 }

+
 STDMETHODIMP CNDSharedEndpoint::
 Bind(const struct sockaddr* pAddress, SIZE_T cbAddress)
 {
-       //???
-       return ND_NOT_SUPPORTED;
+       switch( pAddress->sa_family ){
+       case AF_INET:
+               if( cbAddress < sizeof(sockaddr_in) ){
+                       return ND_INVALID_PARAMETER_2;
+               }
+
+               C_ASSERT( RTL_FIELD_SIZE(CNDSharedEndpoint, m_Address) >= sizeof(sockaddr_in) );
+               ::CopyMemory( &m_Address, pAddress, sizeof(sockaddr_in) );
+               m_AddressSize = sizeof(sockaddr_in);
+               break;
+
+       case AF_INET6:
+               if( cbAddress < sizeof(sockaddr_in6) ){
+                       return ND_INVALID_PARAMETER_2;
+               }
+
+               C_ASSERT( RTL_FIELD_SIZE(CNDSharedEndpoint, m_Address) >= sizeof(sockaddr_in6) );
+               ::CopyMemory( &m_Address, pAddress, sizeof(sockaddr_in6) );
+               m_AddressSize = sizeof(sockaddr_in6);
+               break;
+
+       default:
+               return ND_INVALID_ADDRESS;
+       }
+
+       return ND_SUCCESS;
 }

 STDMETHODIMP CNDSharedEndpoint::
@@ -81,7 +110,7 @@ GetLocalAddress(struct sockaddr* pAddres
        HRESULT hr;

        if (*pcbAddress >= m_AddressSize) {
-               RtlCopyMemory(pAddress, &m_Address, m_AddressSize);
+               ::RtlCopyMemory(pAddress, &m_Address, m_AddressSize);
                hr = ND_SUCCESS;
        } else {
                hr = ND_BUFFER_OVERFLOW;
@@ -90,3 +119,6 @@ GetLocalAddress(struct sockaddr* pAddres
        *pcbAddress = m_AddressSize;
        return NDConvertWVStatus(hr);
 }
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
Index: user/nd_srq.cpp
===================================================================
--- user/nd_srq.cpp     (revision 2848)
+++ user/nd_srq.cpp     (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,39 +28,37 @@
  * SOFTWARE.
  */

+
+#include "precomp.h"
+#include "nd_base.h"
+#include "nd_provider.h"
+#include "nd_adapter.h"
+#include <InitGuid.h>
 #include "nd_srq.h"


-CNDSharedReceiveQueue::CNDSharedReceiveQueue(CNDAdapter *pAdapter)
-{
-       pAdapter->AddRef();
-       m_pAdapter = pAdapter;
-       m_pWvSrq = NULL;
-}
+namespace WinVerbs {
+namespace NetworkDirect {

-STDMETHODIMP CNDSharedReceiveQueue::
-Init(DWORD queueDepth, DWORD maxSGE, DWORD notifyThreshold, GROUP_AFFINITY* pAffinity)
+CNDSharedReceiveQueue::CNDSharedReceiveQueue(CNDAdapter& adapter) :
+       m_pAdapter( &adapter ),
+       m_pWvSrq( NULL )
 {
-       HRESULT hr;
-
-       //??? pAffinity ignored
-       hr = m_pAdapter->m_pWvPd->CreateSharedReceiveQueue(queueDepth, maxSGE,
-                                                                                                          notifyThreshold, &m_pWvSrq);
-       return NDConvertWVStatus(hr);
 }

-CNDSharedReceiveQueue::~CNDSharedReceiveQueue()
+STDMETHODIMP CNDSharedReceiveQueue::
+Init(DWORD queueDepth, DWORD maxSge, DWORD notifyThreshold)
 {
-       if (m_pWvSrq != NULL) {
-               m_pWvSrq->Release();
-       }
-       m_pAdapter->Release();
+       return NDConvertWVStatus(
+               m_pAdapter->Pd()->CreateSharedReceiveQueue(queueDepth, maxSge,
+                                                                                                       notifyThreshold, m_pWvSrq.ref())
+               );
 }

 STDMETHODIMP CNDSharedReceiveQueue::
 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
 {
-       if (riid != IID_IUnknown && riid != IID_INDSharedReceiveQueue) {
+       if (riid != IID_IUnknown && riid != IID_INDSharedReceiveQueue && riid != IID_NDoWVSrq) {
                *ppvObj = NULL;
                return E_NOINTERFACE;
        }
@@ -101,6 +100,12 @@ GetOverlappedResult(OVERLAPPED *pOverlap
 }

 STDMETHODIMP CNDSharedReceiveQueue::
+GetNotifyAffinity(USHORT*, KAFFINITY*)
+{
+       return ND_NOT_SUPPORTED;
+}
+
+STDMETHODIMP CNDSharedReceiveQueue::
 Modify(DWORD queueDepth, DWORD notifyThreshold)
 {
        HRESULT hr;
@@ -118,11 +123,58 @@ Notify(OVERLAPPED* pOverlapped)
        return NDConvertWVStatus(hr);
 }

+#ifdef _WIN64
+C_ASSERT( sizeof(WV_SGE) == sizeof(ND_SGE) );
+C_ASSERT( FIELD_OFFSET(WV_SGE, pAddress) == FIELD_OFFSET( ND_SGE, Buffer ) );
+C_ASSERT( RTL_FIELD_SIZE(WV_SGE, pAddress) == RTL_FIELD_SIZE(ND_SGE, Buffer) );
+C_ASSERT( FIELD_OFFSET(WV_SGE, Length) == FIELD_OFFSET( ND_SGE, BufferLength ) );
+C_ASSERT( RTL_FIELD_SIZE(WV_SGE, Length) == RTL_FIELD_SIZE(ND_SGE, BufferLength) );
+C_ASSERT( FIELD_OFFSET(WV_SGE, Lkey) == FIELD_OFFSET( ND_SGE, MemoryRegionToken ) );
+C_ASSERT( RTL_FIELD_SIZE(WV_SGE, Lkey) == RTL_FIELD_SIZE(ND_SGE, MemoryRegionToken) );
+
 STDMETHODIMP CNDSharedReceiveQueue::
-Receive(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE)
+Receive(VOID* requestContext, const ND_SGE* pSge, DWORD nSge)
 {
-       HRESULT hr;
+       HRESULT hr = m_pWvSrq->PostReceive(reinterpret_cast<ULONG_PTR>(requestContext),
+                                                                          reinterpret_cast<WV_SGE*>(const_cast<ND_SGE*>(pSge)),
+                                                                          nSge);
+       return NDConvertWVStatus(hr);
+}
+#else
+STDMETHODIMP CNDSharedReceiveQueue::
+Receive(VOID* requestContext, const ND_SGE* pSge, DWORD nSge)
+{
+       WV_SGE sge[4];
+       WV_SGE *pShadowSge;

-       hr = m_pWvSrq->PostReceive((UINT64) (ULONG_PTR) requestContext, (WV_SGE *) pSGE, nSGE);
+       if( nSge > _countof(sge) ){
+               pShadowSge = new WV_SGE[nSge];
+               if( pShadowSge == NULL ){
+                       return ND_NO_MEMORY;
+               }
+       }
+       else{
+               pShadowSge = sge;
+       }
+
+       for( DWORD i = 0; i < nSge; i++ ){
+               pShadowSge->pAddress = pSge[i].Buffer;
+               pShadowSge->Reserved = 0;
+               pShadowSge->Length = pSge[i].BufferLength;
+               pShadowSge->Lkey = pSge[i].MemoryRegionToken;
+       }
+
+       HRESULT hr = m_pWvSrq->PostReceive(
+               reinterpret_cast<ULONG_PTR>(requestContext), pShadowSge, nSge);
+
+       if( nSge > _countof(sge) ){
+               delete[] pShadowSge;
+       }
        return NDConvertWVStatus(hr);
 }
+#endif
+
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
+
Index: user/nd_cq.h
===================================================================
--- user/nd_cq.h        (revision 2848)
+++ user/nd_cq.h        (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,14 +33,45 @@
 #ifndef _ND_CQ_H_
 #define _ND_CQ_H_

-#include <initguid.h>
-#include <ndspi.h>
-#include "nd_base.h"
-#include "nd_adapter.h"

-class CNDCompletionQueue : public INDCompletionQueue, public CNDBase
+namespace WinVerbs {
+namespace NetworkDirect {
+
+// {2B2F18C3-C470-4A33-A7E6-1A27A9DD7A95}
+DEFINE_GUID(IID_NDoWVCq,
+0x2b2f18c3, 0xc470, 0x4a33, 0xa7, 0xe6, 0x1a, 0x27, 0xa9, 0xdd, 0x7a, 0x95);
+
+
+class CNDCompletionQueue : public INDCompletionQueue, private CNDBase
 {
+       auto_ref<IWVCompletionQueue> m_pWvCq;
+       auto_ref<CNDAdapter>             m_pAdapter;
+
+private:
+       CNDCompletionQueue(CNDAdapter& adapter);
+       STDMETHODIMP Init(DWORD queueDepth);
+       static STDMETHODIMP_(HRESULT) ConvertStatus(WV_WC_STATUS Status);
+
 public:
+       static STDMETHODIMP
+       CreateInstance(CNDAdapter &adapter, DWORD queueDepth, USHORT,
+                                  KAFFINITY, VOID** ppCq)
+       {
+               auto_ref<CNDCompletionQueue> cq(new CNDCompletionQueue(adapter));
+               if (cq.get() == NULL) {
+                       return ND_NO_MEMORY;
+               }
+
+               HRESULT hr = cq->Init(queueDepth);
+               if (SUCCEEDED(hr)) {
+                       *ppCq = cq.detach();
+               }
+
+               return hr;
+       }
+
+       IWVCompletionQueue* Cq(){ return m_pWvCq.get(); }
+
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
@@ -50,46 +82,14 @@ public:
        STDMETHODIMP GetOverlappedResult(OVERLAPPED *pOverlapped, BOOL bWait);

        // INDCompletionQueue methods
+       STDMETHODIMP GetNotifyAffinity(USHORT* pGroup, KAFFINITY* pAffinity);
        STDMETHODIMP Resize(DWORD queueDepth);
        STDMETHODIMP Notify(DWORD type, OVERLAPPED* pOverlapped);
        STDMETHODIMP_(DWORD) GetResults(ND_RESULT results[], DWORD nResults);

-       CNDCompletionQueue(CNDAdapter *pAdapter);
-       ~CNDCompletionQueue();
-       void Delete() {delete this;}
-       static STDMETHODIMP
-       CreateInstance(CNDAdapter *pAdapter, DWORD queueDepth, INDCompletionQueue** ppCq)
-       {
-               HRESULT hr;
-               CNDCompletionQueue *cq;
-
-               cq = new CNDCompletionQueue(pAdapter);
-               if (cq == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err1;
-               }
-
-               hr = cq->Init(queueDepth);
-               if (FAILED(hr)) {
-                       goto err2;
-               }
-
-               *ppCq = cq;
-               return ND_SUCCESS;
-
-       err2:
-               cq->Release();
-       err1:
-               *ppCq = NULL;
-               return hr;
-       }
-
-       IWVCompletionQueue      *m_pWvCq;
-
-protected:
-       CNDAdapter                      *m_pAdapter;
-       STDMETHODIMP            Init(DWORD queueDepth);
-       STDMETHODIMP_(HRESULT) ConvertStatus(WV_WC_STATUS Status);
 };
+
+} // namespace NetworkDirect
+} // namespace WinVerbs

 #endif // _ND_CQ_H_
Index: user/nd_ep.h
===================================================================
--- user/nd_ep.h        (revision 2848)
+++ user/nd_ep.h        (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,15 +33,39 @@
 #ifndef _ND_ENDPOINT_H_
 #define _ND_ENDPOINT_H_

-#include <initguid.h>
-#include <ndspi.h>
-#include "nd_base.h"
-#include "nd_adapter.h"

+namespace WinVerbs {
+namespace NetworkDirect {

-class CNDSharedEndpoint : public INDSharedEndpoint, public CNDBase
+// {56907B90-4F9B-426C-A91C-FE89BF9719F8}
+DEFINE_GUID(IID_NDoWVSep,
+0x56907b90, 0x4f9b, 0x426c, 0xa9, 0x1c, 0xfe, 0x89, 0xbf, 0x97, 0x19, 0xf8);
+
+class CNDSharedEndpoint : public INDSharedEndpoint, private CNDBase
 {
+       SOCKADDR_STORAGE                m_Address;
+       SIZE_T                                  m_AddressSize;
+       auto_ref<CNDAdapter>    m_pAdapter;
+
+private:
+       CNDSharedEndpoint(CNDAdapter& adapter);
+
 public:
+       static STDMETHODIMP
+       CreateInstance(CNDAdapter& adapter, VOID** ppSharedEndpoint)
+       {
+               auto_ref<CNDSharedEndpoint> ep(new CNDSharedEndpoint(adapter));
+               if (ep.get() == NULL) {
+                       return ND_NO_MEMORY;
+               }
+
+               *ppSharedEndpoint = ep.detach();
+               return ND_SUCCESS;
+       }
+
+    const struct sockaddr* Addr(){ return reinterpret_cast<sockaddr*>(&m_Address); }
+    SIZE_T AddrLen(){ return m_AddressSize; }
+
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
@@ -49,33 +74,9 @@ public:
        // INDEndpoint methods
        STDMETHODIMP Bind(const struct sockaddr* pAddress, SIZE_T cbAddress);
        STDMETHODIMP GetLocalAddress(struct sockaddr* pAddress, SIZE_T* pcbAddress);
-
-       CNDSharedEndpoint(CNDAdapter *pAdapter);
-       ~CNDSharedEndpoint();
-       void Delete() {delete this;}
-       static STDMETHODIMP
-       CreateInstance(CNDAdapter *pAdapter, INDSharedEndpoint** ppSharedEndpoint)
-       {
-               HRESULT hr;
-               CNDSharedEndpoint *ep;
-
-               ep = new CNDSharedEndpoint(pAdapter);
-               if (ep == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err;
-               }
-
-               *ppSharedEndpoint = ep;
-               return ND_SUCCESS;
-
-       err:
-               *ppSharedEndpoint = NULL;
-               return hr;
-       }
-
-       SOCKADDR_STORAGE        m_Address;
-       SIZE_T                          m_AddressSize;
-       CNDAdapter                      *m_pAdapter;
 };
+
+} // namespace NetworkDirect
+} // namespace WinVerbs

 #endif // _ND_ENDPOINT_H_
Index: user/nd_base.cpp
===================================================================
--- user/nd_base.cpp    (revision 2848)
+++ user/nd_base.cpp    (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -27,18 +28,45 @@
  * SOFTWARE.
  */

+#include "precomp.h"
 #include "nd_base.h"
-#include <ndstatus.h>

-CNDBase::CNDBase()
+
+namespace WinVerbs {
+namespace NetworkDirect {
+
+volatile LONG CNDBase::m_nObj = 0;
+
+CNDBase::CNDBase() :
+       m_nRef( 1 )
 {
-       m_nRef = 1;
+       ::InterlockedIncrement( &m_nObj );
+}
+
+CNDBase::CNDBase(const CNDBase&) :
+       m_nRef( 1 )
+{
+       // New object, so we increment m_nObj, but the ref count is 1.
+       ::InterlockedIncrement( &m_nObj );
+}
+
+CNDBase& CNDBase::operator =(const CNDBase&)
+{
+       // Both objects already exist, don't touch m_nObj.
+       // Don't copy the ref count, either, as that could result
+       // in improper behavior.
+       return *this;
+}
+
+CNDBase::~CNDBase()
+{
+       ::InterlockedDecrement( &m_nObj );
 }

 STDMETHODIMP_(ULONG) CNDBase::
 AddRef(void)
 {
-       return InterlockedIncrement(&m_nRef);
+       return ::InterlockedIncrement(&m_nRef);
 }

 STDMETHODIMP_(ULONG) CNDBase::
@@ -46,19 +74,23 @@ Release(void)
 {
        ULONG ref;

-       ref = (ULONG) InterlockedDecrement(&m_nRef);
-       if (ref == 0) {
-               Delete();
+       ref = (ULONG)::InterlockedDecrement(&m_nRef);
+       if (ref == 0){
+               delete this;
        }
        return ref;
 }

 HRESULT NDConvertWVStatus(HRESULT hr)
 {
-       switch (hr) {
+       switch (hr){
        case WV_IO_PENDING:
                return ND_PENDING;
        default:
                return hr;
        }
 }
+
+
+} // namespace NetworkDirect
+} // namespace WinVerbs
Index: user/nd_srq.h
===================================================================
--- user/nd_srq.h       (revision 2848)
+++ user/nd_srq.h       (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,15 +33,47 @@
 #ifndef _ND_SRQ_H_
 #define _ND_SRQ_H_

-#include <initguid.h>
-#include <ndspi.h>
-#include "nd_base.h"
-#include "nd_adapter.h"

+namespace WinVerbs {
+namespace NetworkDirect {

-class CNDSharedReceiveQueue : public INDSharedReceiveQueue, public CNDBase
+// {1DD359B4-0176-442D-9C72-5873501B0FA2}
+DEFINE_GUID(IID_NDoWVSrq,
+0x1dd359b4, 0x176, 0x442d, 0x9c, 0x72, 0x58, 0x73, 0x50, 0x1b, 0xf, 0xa2);
+
+
+class CNDSharedReceiveQueue : public INDSharedReceiveQueue, private CNDBase
 {
+       auto_ref<IWVSharedReceiveQueue> m_pWvSrq;
+       auto_ref<CNDAdapter>                    m_pAdapter;
+
+private:
+       CNDSharedReceiveQueue(CNDAdapter& adapter);
+
+       STDMETHODIMP Init(DWORD queueDepth, DWORD maxSGE, DWORD notifyThreshold);
+
 public:
+       static STDMETHODIMP
+       CreateInstance(CNDAdapter& adapter, DWORD queueDepth, DWORD maxSGE,
+                                  DWORD notifyThreshold, USHORT, KAFFINITY,
+                                  VOID** ppSharedReceiveQueue)
+       {
+               // Affinity is ignored for now.
+               auto_ref<CNDSharedReceiveQueue> srq( new CNDSharedReceiveQueue(adapter));
+               if (srq.get() == NULL) {
+                       return ND_NO_MEMORY;
+               }
+
+               HRESULT hr = srq->Init(queueDepth, maxSGE, notifyThreshold);
+               if (SUCCEEDED(hr)) {
+                       *ppSharedReceiveQueue = srq.detach();
+               }
+
+               return hr;
+       }
+
+       IWVSharedReceiveQueue* Srq(){ return m_pWvSrq.get(); }
+
        // IUnknown methods
        STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR* ppvObj);
        STDMETHODIMP_(ULONG) AddRef();
@@ -51,49 +84,15 @@ public:
        STDMETHODIMP GetOverlappedResult(OVERLAPPED *pOverlapped, BOOL bWait);

        // INDSharedReceiveQueue methods
+       STDMETHODIMP GetNotifyAffinity(USHORT* pGroup, KAFFINITY* pAffinity);
        STDMETHODIMP Modify(DWORD queueDepth, DWORD notifyThreshold);
        STDMETHODIMP Notify(OVERLAPPED* pOverlapped);
-       STDMETHODIMP Receive(VOID* requestContext, const ND_SGE* pSGE, DWORD nSGE);
-
-       CNDSharedReceiveQueue(CNDAdapter *pAdapter);
-       ~CNDSharedReceiveQueue();
-       void Delete() {delete this;}
-       static STDMETHODIMP
-       CreateInstance(CNDAdapter *pAdapter, DWORD queueDepth, DWORD maxSGE,
-                                  DWORD notifyThreshold, GROUP_AFFINITY* pAffinity,
-                                  INDSharedReceiveQueue** ppSharedReceiveQueue)
-       {
-               HRESULT hr;
-               CNDSharedReceiveQueue *srq;
-
-               srq = new CNDSharedReceiveQueue(pAdapter);
-               if (srq == NULL) {
-                       hr = ND_NO_MEMORY;
-                       goto err1;
-               }
-
-               hr = srq->Init(queueDepth, maxSGE, notifyThreshold, pAffinity);
-               if (FAILED(hr)) {
-                       goto err2;
-               }
-
-               *ppSharedReceiveQueue = srq;
-               return ND_SUCCESS;
-
-       err2:
-               srq->Release();
-       err1:
-               *ppSharedReceiveQueue = NULL;
-               return hr;
-       }
+       STDMETHODIMP Receive(VOID* requestContext, const ND_SGE* pSge, DWORD nSge);

-       IWVSharedReceiveQueue   *m_pWvSrq;
+};

-protected:
-       CNDAdapter                              *m_pAdapter;
+} // namespace NetworkDirect
+} // namespace WinVerbs

-       STDMETHODIMP Init(DWORD queueDepth, DWORD maxSGE, DWORD notifyThreshold,
-                                         GROUP_AFFINITY* pAffinity);
-};

 #endif // _ND_SRQ_H_
Index: inc/user/rdma/winverbs.h
===================================================================
--- inc/user/rdma/winverbs.h    (revision 2833)
+++ inc/user/rdma/winverbs.h    (working copy)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1996-2008 Intel Corporation. All rights reserved.
+ * Copyright (c) 2010 Microsoft Corporation.  All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -32,8 +33,6 @@
 #ifndef _WINVERBS_H_
 #define _WINVERBS_H_

-#include <initguid.h>
-
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <unknwn.h>
@@ -252,6 +251,7 @@ typedef struct _WV_MEMORY_KEYS
 #define WV_ACCESS_REMOTE_ATOMIC                        0x00000004
 #define WV_ACCESS_LOCAL_WRITE                  0x00000008
 #define WV_ACCESS_MW_BIND                              0x00000010
+#define WV_ACCESS_CACHABLE                             0x00000020

 // Send queue operation flags
 #define WV_SEND_IMMEDIATE                              0x00000001
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nd2.patch
Type: application/octet-stream
Size: 97718 bytes
Desc: nd2.patch
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20100724/a8eb7df1/attachment.obj>


More information about the ofw mailing list