netdirect: add winverbs ND provider
[mirror/winof/.git] / ulp / netdirect / user / nd_listen.cpp
1 /*\r
2  * Copyright (c) 2009 Intel Corporation. All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenIB.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  */\r
29 \r
30 #include "nd_listen.h"\r
31 #include "nd_adapter.h"\r
32 #include "nd_connect.h"\r
33 \r
34 \r
35 CNDListen::CNDListen(CNDAdapter *pAdapter)\r
36 {\r
37         pAdapter->AddRef();\r
38         m_pAdapter = pAdapter;\r
39         m_pWvConnEp = NULL;\r
40 }\r
41 \r
42 STDMETHODIMP CNDListen::\r
43 Init(SIZE_T Backlog, INT Protocol, USHORT *pPort)\r
44 {\r
45         WV_CONNECT_ATTRIBUTES attr;\r
46         WV_SOCKADDR addr;\r
47         HRESULT hr;\r
48 \r
49         if (Protocol != 6) {\r
50                 return ND_NOT_SUPPORTED;\r
51         }\r
52 \r
53         hr = m_pAdapter->m_pWvProvider->CreateConnectEndpoint(&m_pWvConnEp);\r
54         if (FAILED(hr)) {\r
55                 return hr;\r
56         }\r
57 \r
58         if (m_pAdapter->m_Address.ss_family == AF_INET) {\r
59                 RtlCopyMemory(&addr.Sin, &m_pAdapter->m_Address, sizeof(addr.Sin));\r
60                 addr.Sin.sin_port = *pPort;\r
61         } else {\r
62                 RtlCopyMemory(&addr.Sin6, &m_pAdapter->m_Address, sizeof(addr.Sin6));\r
63                 addr.Sin6.sin6_port = *pPort;\r
64         }\r
65 \r
66         hr = m_pWvConnEp->BindAddress(&addr.Sa);\r
67         if (FAILED(hr)) {\r
68                 goto err;\r
69         }\r
70 \r
71         hr = m_pWvConnEp->Listen(Backlog);\r
72         if (FAILED(hr)) {\r
73                 goto err;\r
74         }\r
75 \r
76         if (*pPort == 0) {\r
77                 hr = m_pWvConnEp->Query(&attr);\r
78                 if (FAILED(hr)) {\r
79                         goto err;\r
80                 }\r
81                 *pPort = (addr.Sa.sa_family == AF_INET) ?\r
82                                  attr.LocalAddress.Sin.sin_port : attr.LocalAddress.Sin6.sin6_port;\r
83         }\r
84 \r
85         return ND_SUCCESS;\r
86 err:\r
87         m_pWvConnEp->Release();\r
88         return hr;\r
89 }\r
90 \r
91 CNDListen::~CNDListen()\r
92 {\r
93         if (m_pWvConnEp != NULL) {\r
94                 m_pWvConnEp->Release();\r
95         }\r
96         m_pAdapter->Release();\r
97 }\r
98 \r
99 STDMETHODIMP CNDListen::\r
100 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)\r
101 {\r
102         if (riid != IID_IUnknown && riid != IID_INDListen) {\r
103                 *ppvObj = NULL;\r
104                 return E_NOINTERFACE;\r
105         }\r
106 \r
107         *ppvObj = this;\r
108         AddRef();\r
109         return ND_SUCCESS;\r
110 }\r
111 \r
112 STDMETHODIMP_(ULONG) CNDListen::\r
113 AddRef(void)\r
114 {\r
115         return CNDBase::AddRef();\r
116 }\r
117 \r
118 STDMETHODIMP_(ULONG) CNDListen::\r
119 Release(void)\r
120 {\r
121         return CNDBase::Release();\r
122 }\r
123 \r
124 STDMETHODIMP CNDListen::\r
125 CancelOverlappedRequests(void)\r
126 {\r
127         return m_pWvConnEp->CancelOverlappedRequests();\r
128 }\r
129 \r
130 STDMETHODIMP CNDListen::\r
131 GetOverlappedResult(OVERLAPPED *pOverlapped,\r
132                                         SIZE_T *pNumberOfBytesTransferred, BOOL bWait)\r
133 {\r
134         return m_pWvConnEp->GetOverlappedResult(pOverlapped,\r
135                                                                                         (DWORD *) pNumberOfBytesTransferred,\r
136                                                                                         bWait);\r
137 }\r
138 \r
139 STDMETHODIMP CNDListen::\r
140 GetConnectionRequest(INDConnector* pConnector, OVERLAPPED* pOverlapped)\r
141 {\r
142         CNDConnector *conn = (CNDConnector *) pConnector;\r
143 \r
144         return m_pWvConnEp->GetRequest(conn->m_pWvConnEp, pOverlapped);\r
145 }\r