winverbs: map WSA error codes to winverbs status values
[mirror/winof/.git] / core / winverbs / user / wv_ep.cpp
1 /*\r
2  * Copyright (c) 2008 Intel Corporation. All rights reserved.\r
3  * Portions Copyright (c) 2009 Microsoft Corporation.  All rights reserved.\r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  */\r
30 \r
31 #include "wv_memory.h"\r
32 #include "wv_ep.h"\r
33 #include "wv_ioctl.h"\r
34 #include "wv_qp.h"\r
35 \r
36 static void WvIoConvertConnParam(WV_IO_CONNECT_PARAM *pIoParam,\r
37                                                                  WV_CONNECT_PARAM *pParam)\r
38 {\r
39         pIoParam->DataLength = (UINT8) pParam->DataLength;\r
40         pIoParam->ResponderResources = pParam->ResponderResources;\r
41         pIoParam->InitiatorDepth = pParam->InitiatorDepth;\r
42         pIoParam->RetryCount = pParam->RetryCount;\r
43         pIoParam->RnrRetryCount = pParam->RnrRetryCount;\r
44         RtlZeroMemory(pIoParam->Reserved, sizeof pIoParam->Reserved);\r
45         RtlCopyMemory(pIoParam->Data, pParam->Data, pParam->DataLength);\r
46 }\r
47 \r
48 CWVConnectEndpoint::CWVConnectEndpoint(CWVProvider *pProvider)\r
49 {\r
50         pProvider->AddRef();\r
51         m_pProvider = pProvider;\r
52         m_hFile = pProvider->m_hFile;\r
53         m_Socket = INVALID_SOCKET;\r
54         m_pQp = NULL;\r
55 }\r
56 \r
57 STDMETHODIMP CWVConnectEndpoint::\r
58 Allocate(void)\r
59 {\r
60         UINT64                  EpType;\r
61         DWORD                   bytes;\r
62         HRESULT                 hr;\r
63 \r
64         EpType = WV_IO_EP_TYPE_CONNECT;\r
65         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CREATE, &EpType, sizeof EpType,\r
66                                                   &m_Id, sizeof m_Id, &bytes, NULL)) {\r
67                 hr = WV_SUCCESS;\r
68         } else {\r
69                 hr = HRESULT_FROM_WIN32(GetLastError());\r
70         }\r
71 \r
72         return hr;\r
73 }\r
74 \r
75 CWVConnectEndpoint::~CWVConnectEndpoint()\r
76 {\r
77         DWORD   bytes;\r
78 \r
79         if (m_pQp != NULL) {\r
80                 m_pQp->Release();\r
81         }\r
82 \r
83         if (m_Id != 0) {\r
84                 WvDeviceIoControl(m_hFile, WV_IOCTL_EP_DESTROY, &m_Id, sizeof m_Id,\r
85                                                   NULL, 0, &bytes, NULL);\r
86         }\r
87 \r
88         if (m_Socket != INVALID_SOCKET) {\r
89                 closesocket(m_Socket);\r
90         }\r
91         m_pProvider->Release();\r
92 }\r
93 \r
94 STDMETHODIMP CWVConnectEndpoint::\r
95 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)\r
96 {\r
97         if (riid != IID_IUnknown && riid != IID_IWVEndpoint &&\r
98                 riid != IID_IWVConnectEndpoint) {\r
99                 *ppvObj = NULL;\r
100                 return E_NOINTERFACE;\r
101         }\r
102 \r
103         *ppvObj = this;\r
104         AddRef();\r
105         return WV_SUCCESS;\r
106 }\r
107 \r
108 STDMETHODIMP_(ULONG) CWVConnectEndpoint::\r
109 AddRef(void)\r
110 {\r
111         return CWVBase::AddRef();\r
112 }\r
113 \r
114 STDMETHODIMP_(ULONG) CWVConnectEndpoint::\r
115 Release(void)\r
116 {\r
117         return CWVBase::Release();\r
118 }\r
119 \r
120 STDMETHODIMP CWVConnectEndpoint::\r
121 CancelOverlappedRequests(void)\r
122 {\r
123         DWORD   bytes;\r
124 \r
125         return WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CANCEL, &m_Id, sizeof m_Id,\r
126                                                          NULL, 0, &bytes, NULL) ?\r
127                                                          WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());\r
128 }\r
129 \r
130 STDMETHODIMP CWVConnectEndpoint::\r
131 GetOverlappedResult(OVERLAPPED *pOverlapped,\r
132                                         DWORD *pNumberOfBytesTransferred, BOOL bWait)\r
133 {\r
134         ::GetOverlappedResult(m_hFile, pOverlapped, pNumberOfBytesTransferred, bWait);\r
135         return (HRESULT) pOverlapped->Internal;\r
136 }\r
137 \r
138 STDMETHODIMP CWVConnectEndpoint::\r
139 Modify(DWORD Option, const VOID* pOptionData, SIZE_T OptionLength)\r
140 {\r
141         WV_IO_ID                        *pId;\r
142         DWORD                           bytes;\r
143         HRESULT                         hr;\r
144         CWVBuffer                       buf;\r
145 \r
146         bytes = sizeof WV_IO_ID + OptionLength;\r
147         pId = (WV_IO_ID *) buf.Get(bytes);\r
148         if (pId == NULL) {\r
149                 return WV_NO_MEMORY;\r
150         }\r
151 \r
152         pId->Id = m_Id;\r
153         pId->Data = Option;\r
154         RtlCopyMemory(pId + 1, pOptionData, OptionLength);\r
155 \r
156         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_MODIFY, pId, bytes,\r
157                                                   NULL, 0, &bytes, NULL)) {\r
158                 hr = WV_SUCCESS;\r
159         } else {\r
160                 hr = HRESULT_FROM_WIN32(GetLastError());\r
161         }\r
162 \r
163         buf.Put();\r
164         return hr;\r
165 }\r
166 \r
167 STDMETHODIMP CWVConnectEndpoint::\r
168 BindAddress(SOCKADDR* pAddress)\r
169 {\r
170         WV_IO_EP_BIND           attr;\r
171         BOOLEAN                         any;\r
172         DWORD                           bytes;\r
173         int                                     len;\r
174         HRESULT                         hr;\r
175 \r
176         if (pAddress->sa_family == AF_INET) {\r
177                 any = (((SOCKADDR_IN *) pAddress)->sin_addr.S_un.S_addr == INADDR_ANY);\r
178                 bytes = sizeof(SOCKADDR_IN);\r
179         } else {\r
180                 any = IN6ADDR_ISANY((SOCKADDR_IN6 *) pAddress);\r
181                 bytes = sizeof(SOCKADDR_IN6);\r
182         }\r
183 \r
184         if (any) {\r
185                 RtlZeroMemory(&attr.Device, sizeof attr.Device);\r
186         } else {\r
187                 hr = m_pProvider->TranslateAddress(pAddress, (WV_DEVICE_ADDRESS *) &attr.Device);\r
188                 if (FAILED(hr)) {\r
189                         return hr;\r
190                 }\r
191         }\r
192 \r
193         m_Socket = socket(pAddress->sa_family, SOCK_STREAM, IPPROTO_TCP);\r
194         if (m_Socket == INVALID_SOCKET) {\r
195                 return WvConvertWSAStatus(WSAGetLastError());\r
196         }\r
197 \r
198         hr = bind(m_Socket, pAddress, bytes);\r
199         if (FAILED(hr)) {\r
200                 goto get_err;\r
201         }\r
202 \r
203         attr.Id = m_Id;\r
204         len = sizeof attr.Address;\r
205         hr = getsockname(m_Socket, (sockaddr *) &attr.Address, &len);\r
206         if (FAILED(hr)) {\r
207                 goto get_err;\r
208         }\r
209 \r
210         if (!WvDeviceIoControl(m_hFile, WV_IOCTL_EP_BIND, &attr, sizeof attr,\r
211                                                    &attr, sizeof attr, &bytes, NULL)) {\r
212                 hr = HRESULT_FROM_WIN32(GetLastError());\r
213                 goto err;\r
214         }\r
215 \r
216         return WV_SUCCESS;\r
217 \r
218 get_err:\r
219         hr = WvConvertWSAStatus(WSAGetLastError());\r
220 err:\r
221         closesocket(m_Socket);\r
222         m_Socket = INVALID_SOCKET;\r
223         return hr;\r
224 }\r
225 \r
226 STDMETHODIMP CWVConnectEndpoint::\r
227 Listen(SIZE_T Backlog)\r
228 {\r
229         WV_IO_EP_LISTEN         attr;\r
230         DWORD                           bytes;\r
231         HRESULT                         hr;\r
232 \r
233         attr.Id = m_Id;\r
234         attr.Backlog = Backlog;\r
235 \r
236         if (!WvDeviceIoControl(m_hFile, WV_IOCTL_EP_LISTEN, &attr, sizeof attr,\r
237                                                    &attr, sizeof attr, &bytes, NULL)) {\r
238                 hr = HRESULT_FROM_WIN32(GetLastError());\r
239         } else {\r
240                 hr = WV_SUCCESS;\r
241         }\r
242 \r
243         return hr;\r
244 }\r
245 \r
246 STDMETHODIMP CWVConnectEndpoint::\r
247 Reject(const VOID* pUserData, SIZE_T UserDataLength)\r
248 {\r
249         WV_IO_ID                        *pId;\r
250         DWORD                           bytes;\r
251         HRESULT                         hr;\r
252         CWVBuffer                       buf;\r
253 \r
254         bytes = sizeof WV_IO_ID + UserDataLength;\r
255         pId = (WV_IO_ID *) buf.Get(bytes);\r
256         if (pId == NULL) {\r
257                 return WV_NO_MEMORY;\r
258         }\r
259 \r
260         pId->Id = m_Id;\r
261         RtlCopyMemory(pId + 1, pUserData, UserDataLength);\r
262 \r
263         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_REJECT, pId, bytes,\r
264                                                   NULL, 0, &bytes, NULL)) {\r
265                 hr = WV_SUCCESS;\r
266         } else {\r
267                 hr = HRESULT_FROM_WIN32(GetLastError());\r
268         }\r
269 \r
270         buf.Put();\r
271         return hr;\r
272 }\r
273 \r
274 STDMETHODIMP CWVConnectEndpoint::\r
275 GetRequest(IWVConnectEndpoint* pEndpoint, OVERLAPPED* pOverlapped)\r
276 {\r
277         WV_IO_EP_GET_REQUEST    req;\r
278         DWORD                                   bytes;\r
279         HRESULT                                 hr;\r
280 \r
281         req.Id = m_Id;\r
282         req.EpId = ((CWVConnectEndpoint *) pEndpoint)->m_Id;\r
283         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_GET_REQUEST,\r
284                                                   &req, sizeof req, NULL, 0, &bytes, pOverlapped)) {\r
285                 hr = WV_SUCCESS;\r
286         } else {\r
287                 hr = HRESULT_FROM_WIN32(GetLastError());\r
288         }\r
289 \r
290         return hr;\r
291 }\r
292 \r
293 STDMETHODIMP CWVConnectEndpoint::\r
294 Connect(IWVConnectQueuePair* pQp, const SOCKADDR* pAddress,\r
295                 WV_CONNECT_PARAM* pParam, OVERLAPPED* pOverlapped)\r
296 {\r
297         WV_IO_EP_CONNECT        attr;\r
298         DWORD                           bytes;\r
299         HRESULT                         hr;\r
300 \r
301         m_pQp = (CWVConnectQueuePair *) pQp;\r
302         m_pQp->AddRef();\r
303         attr.Id = m_Id;\r
304         attr.QpId = m_pQp->m_Id;\r
305 \r
306         if (pAddress->sa_family == AF_INET) {\r
307                 RtlCopyMemory(&attr.PeerAddress, pAddress, sizeof(SOCKADDR_IN));\r
308         } else {\r
309                 RtlCopyMemory(&attr.PeerAddress, pAddress, sizeof(SOCKADDR_IN6));\r
310         }\r
311         WvIoConvertConnParam(&attr.Param, pParam);\r
312 \r
313         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CONNECT, &attr, sizeof attr,\r
314                                                   NULL, 0, &bytes, pOverlapped)) {\r
315                 hr = WV_SUCCESS;\r
316         } else {\r
317                 hr = HRESULT_FROM_WIN32(GetLastError());\r
318         }\r
319 \r
320         return hr;\r
321 }\r
322 \r
323 STDMETHODIMP CWVConnectEndpoint::\r
324 Accept(IWVConnectQueuePair* pQp, WV_CONNECT_PARAM* pParam, OVERLAPPED* pOverlapped)\r
325 {\r
326         WV_IO_EP_ACCEPT         attr;\r
327         DWORD                           bytes;\r
328         HRESULT                         hr;\r
329         void                            *pout;\r
330         DWORD                           size;\r
331 \r
332         if (m_pQp == NULL) {\r
333                 m_pQp = (CWVConnectQueuePair *) pQp;\r
334                 m_pQp->AddRef();\r
335         }\r
336 \r
337         attr.Id = m_Id;\r
338         attr.QpId = m_pQp->m_Id;\r
339         m_pQp->m_pVerbs->nd_modify_qp(m_pQp->m_hVerbsQp, &pout, &size);\r
340         WvIoConvertConnParam(&attr.Param, pParam);\r
341 \r
342         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_ACCEPT, &attr, sizeof attr,\r
343                                                   pout, size, &bytes, pOverlapped)) {\r
344                 hr = WV_SUCCESS;\r
345         } else {\r
346                 hr = HRESULT_FROM_WIN32(GetLastError());\r
347         }\r
348 \r
349         return hr;\r
350 }\r
351 \r
352 STDMETHODIMP CWVConnectEndpoint::\r
353 Disconnect(OVERLAPPED* pOverlapped)\r
354 {\r
355         WV_IO_EP_DISCONNECT     attr;\r
356         DWORD                           bytes;\r
357         HRESULT                         hr;\r
358         void                            *pout;\r
359         DWORD                           size;\r
360 \r
361         attr.Id = m_Id;\r
362         attr.QpId = m_pQp->m_Id;\r
363         m_pQp->m_pVerbs->nd_modify_qp(m_pQp->m_hVerbsQp, &pout, &size);\r
364 \r
365         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_DISCONNECT,\r
366                                                   &attr, sizeof attr, pout, size, &bytes, pOverlapped)) {\r
367                 hr = WV_SUCCESS;\r
368         } else {\r
369                 hr = HRESULT_FROM_WIN32(GetLastError());\r
370         }\r
371 \r
372         return hr;\r
373 }\r
374 \r
375 STDMETHODIMP CWVConnectEndpoint::\r
376 NotifyDisconnect(OVERLAPPED* pOverlapped)\r
377 {\r
378         DWORD           bytes;\r
379         HRESULT         hr;\r
380 \r
381         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_DISCONNECT_NOTIFY,\r
382                                                   &m_Id, sizeof m_Id, NULL, 0, &bytes, pOverlapped)) {\r
383                 hr = WV_SUCCESS;\r
384         } else {\r
385                 hr = HRESULT_FROM_WIN32(GetLastError());\r
386         }\r
387 \r
388         return hr;\r
389 }\r
390 \r
391 STDMETHODIMP CWVConnectEndpoint::\r
392 Query(WV_CONNECT_ATTRIBUTES* pAttributes)\r
393 {\r
394         WV_IO_EP_ATTRIBUTES     attr;\r
395         DWORD                           bytes;\r
396         HRESULT                         hr;\r
397 \r
398         if (!WvDeviceIoControl(m_hFile, WV_IOCTL_EP_QUERY, &m_Id, sizeof m_Id,\r
399                                                    &attr, sizeof attr, &bytes, NULL)) {\r
400                 return HRESULT_FROM_WIN32(GetLastError());\r
401         }\r
402 \r
403         RtlCopyMemory(&pAttributes->LocalAddress, &attr.LocalAddress,\r
404                                   sizeof pAttributes->LocalAddress);\r
405         RtlCopyMemory(&pAttributes->PeerAddress, &attr.PeerAddress,\r
406                                   sizeof pAttributes->PeerAddress);\r
407         RtlCopyMemory(&pAttributes->Device, &attr.Device, sizeof pAttributes->Device);\r
408         pAttributes->Param.DataLength = attr.Param.Connect.DataLength;\r
409         pAttributes->Param.ResponderResources = (SIZE_T) attr.Param.Connect.ResponderResources;\r
410         pAttributes->Param.InitiatorDepth = (SIZE_T) attr.Param.Connect.InitiatorDepth;\r
411         pAttributes->Param.RetryCount = attr.Param.Connect.RetryCount;\r
412         pAttributes->Param.RnrRetryCount = attr.Param.Connect.RnrRetryCount;\r
413         RtlCopyMemory(pAttributes->Param.Data, attr.Param.Connect.Data, attr.Param.Connect.DataLength);\r
414 \r
415         return WV_SUCCESS;\r
416 }\r
417 \r
418 \r
419 CWVDatagramEndpoint::CWVDatagramEndpoint(CWVProvider *pProvider)\r
420 {\r
421         pProvider->AddRef();\r
422         m_pProvider = pProvider;\r
423         m_hFile = pProvider->m_hFile;\r
424 }\r
425         \r
426 STDMETHODIMP CWVDatagramEndpoint::\r
427 Allocate(void)\r
428 {\r
429         UINT64                  EpType;\r
430         DWORD                   bytes;\r
431         HRESULT                 hr;\r
432 \r
433         EpType = WV_IO_EP_TYPE_DATAGRAM;\r
434         if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CREATE, &EpType, sizeof EpType,\r
435                                                   &m_Id, sizeof m_Id, &bytes, NULL)) {\r
436                 hr = WV_SUCCESS;\r
437         } else {\r
438                 hr = HRESULT_FROM_WIN32(GetLastError());\r
439         }\r
440 \r
441         return hr;\r
442 }\r
443 \r
444 CWVDatagramEndpoint::~CWVDatagramEndpoint()\r
445 {\r
446         DWORD   bytes;\r
447 \r
448         if (m_Id != 0) {\r
449                 WvDeviceIoControl(m_hFile, WV_IOCTL_EP_DESTROY, &m_Id, sizeof m_Id,\r
450                                                   NULL, 0, &bytes, NULL);\r
451         }\r
452         m_pProvider->Release();\r
453 }\r
454 \r
455 STDMETHODIMP CWVDatagramEndpoint::\r
456 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)\r
457 {\r
458         if (riid != IID_IUnknown && riid != IID_IWVEndpoint &&\r
459                 riid != IID_IWVDatagramEndpoint) {\r
460                 *ppvObj = NULL;\r
461                 return E_NOINTERFACE;\r
462         }\r
463 \r
464         *ppvObj = this;\r
465         AddRef();\r
466         return WV_SUCCESS;\r
467 }\r
468 \r
469 STDMETHODIMP_(ULONG) CWVDatagramEndpoint::\r
470 AddRef(void)\r
471 {\r
472         return CWVBase::AddRef();\r
473 }\r
474 \r
475 STDMETHODIMP_(ULONG) CWVDatagramEndpoint::\r
476 Release(void)\r
477 {\r
478         return CWVBase::Release();\r
479 }\r
480 \r
481 STDMETHODIMP CWVDatagramEndpoint::\r
482 CancelOverlappedRequests(void)\r
483 {\r
484         DWORD   bytes;\r
485 \r
486         return WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CANCEL, &m_Id, sizeof m_Id,\r
487                                                          NULL, 0, &bytes, NULL) ?\r
488                                                          WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());\r
489 }\r
490 \r
491 STDMETHODIMP CWVDatagramEndpoint::\r
492 GetOverlappedResult(OVERLAPPED *pOverlapped,\r
493                                         DWORD *pNumberOfBytesTransferred, BOOL bWait)\r
494 {\r
495         ::GetOverlappedResult(m_hFile, pOverlapped, pNumberOfBytesTransferred, bWait);\r
496         return (HRESULT) pOverlapped->Internal;\r
497 }\r
498 \r
499 STDMETHODIMP CWVDatagramEndpoint::\r
500 Modify(DWORD Option, const VOID* pOptionData, SIZE_T OptionLength)\r
501 {\r
502         UNREFERENCED_PARAMETER(Option);\r
503         UNREFERENCED_PARAMETER(pOptionData);\r
504         UNREFERENCED_PARAMETER(OptionLength);\r
505 \r
506         return E_NOTIMPL;\r
507 }\r
508 \r
509 STDMETHODIMP CWVDatagramEndpoint::\r
510 BindAddress(SOCKADDR* pAddress)\r
511 {\r
512         UNREFERENCED_PARAMETER(pAddress);\r
513 \r
514         return E_NOTIMPL;\r
515 }\r
516 \r
517 STDMETHODIMP CWVDatagramEndpoint::\r
518 Listen(SIZE_T Backlog)\r
519 {\r
520         UNREFERENCED_PARAMETER(Backlog);\r
521 \r
522         return E_NOTIMPL;\r
523 }\r
524 \r
525 STDMETHODIMP CWVDatagramEndpoint::\r
526 Reject(const VOID* pUserData, SIZE_T UserDataLength)\r
527 {\r
528         UNREFERENCED_PARAMETER(pUserData);\r
529         UNREFERENCED_PARAMETER(UserDataLength);\r
530 \r
531         return E_NOTIMPL;\r
532 }\r
533 \r
534 STDMETHODIMP CWVDatagramEndpoint::\r
535 GetRequest(IWVDatagramEndpoint* pEndpoint, OVERLAPPED* pOverlapped)\r
536 {\r
537         UNREFERENCED_PARAMETER(pEndpoint);\r
538         UNREFERENCED_PARAMETER(pOverlapped);\r
539 \r
540         return E_NOTIMPL;\r
541 }\r
542 \r
543 STDMETHODIMP CWVDatagramEndpoint::\r
544 Lookup(const SOCKADDR* pAddress, const VOID* pUserData,\r
545            SIZE_T UserDataLength, OVERLAPPED* pOverlapped)\r
546 {\r
547         UNREFERENCED_PARAMETER(pAddress);\r
548         UNREFERENCED_PARAMETER(pUserData);\r
549         UNREFERENCED_PARAMETER(UserDataLength);\r
550         UNREFERENCED_PARAMETER(pOverlapped);\r
551 \r
552         return E_NOTIMPL;\r
553 }\r
554 \r
555 STDMETHODIMP CWVDatagramEndpoint::\r
556 Accept(WV_DATAGRAM_PARAM* pParam, OVERLAPPED* pOverlapped)\r
557 {\r
558         UNREFERENCED_PARAMETER(pParam);\r
559         UNREFERENCED_PARAMETER(pOverlapped);\r
560 \r
561         return E_NOTIMPL;\r
562 }\r
563 \r
564 STDMETHODIMP CWVDatagramEndpoint::\r
565 JoinMulticast(const SOCKADDR* pAddress, OVERLAPPED* pOverlapped)\r
566 {\r
567         UNREFERENCED_PARAMETER(pAddress);\r
568         UNREFERENCED_PARAMETER(pOverlapped);\r
569 \r
570         return E_NOTIMPL;\r
571 }\r
572 \r
573 STDMETHODIMP CWVDatagramEndpoint::\r
574 LeaveMulticast(const SOCKADDR* pAddress, OVERLAPPED* pOverlapped)\r
575 {\r
576         UNREFERENCED_PARAMETER(pAddress);\r
577         UNREFERENCED_PARAMETER(pOverlapped);\r
578 \r
579         return E_NOTIMPL;\r
580 }\r
581 \r
582 STDMETHODIMP CWVDatagramEndpoint::\r
583 Query(WV_DATAGRAM_ATTRIBUTES* pAttributes)\r
584 {\r
585         UNREFERENCED_PARAMETER(pAttributes);\r
586 \r
587         return E_NOTIMPL;\r
588 }\r