winverbs: fixes to support OFED compatibility libraries and ND
[mirror/winof/.git] / core / winverbs / user / wv_provider.cpp
1 /*\r
2  * Copyright (c) 2008 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 AWV\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 <iba\ib_al.h>\r
31 #include <iba\ib_at_ioctl.h>\r
32 \r
33 #include "wv_memory.h"\r
34 #include "wv_provider.h"\r
35 #include "wv_device.h"\r
36 #include "wv_ep.h"\r
37 #include "wv_ioctl.h"\r
38 \r
39 CWVProvider::CWVProvider()\r
40 {\r
41         InterlockedIncrement(&WvRef);\r
42         m_hFile = INVALID_HANDLE_VALUE;\r
43 }\r
44 \r
45 CWVProvider::~CWVProvider()\r
46 {\r
47         CloseHandle(m_hFile);\r
48         if (InterlockedDecrement(&WvRef) == 0) {\r
49                 WSACleanup();\r
50         }\r
51 }\r
52 \r
53 STDMETHODIMP CWVProvider::\r
54 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)\r
55 {\r
56         if (riid != IID_IUnknown && riid != IID_IWVProvider) {\r
57                 *ppvObj = NULL;\r
58                 return E_NOINTERFACE;\r
59         }\r
60 \r
61         *ppvObj = this;\r
62         AddRef();\r
63         return WV_SUCCESS;\r
64 }\r
65 \r
66 STDMETHODIMP_(ULONG) CWVProvider::\r
67 AddRef(void)\r
68 {\r
69         return CWVBase::AddRef();\r
70 }\r
71 \r
72 STDMETHODIMP_(ULONG) CWVProvider::\r
73 Release(void)\r
74 {\r
75         return CWVBase::Release();\r
76 }\r
77 \r
78 STDMETHODIMP_(HANDLE) CWVProvider::\r
79 GetFileHandle(void)\r
80 {\r
81         return m_hFile;\r
82 }\r
83 \r
84 STDMETHODIMP CWVProvider::\r
85 QueryDeviceList(NET64* pGuidList, SIZE_T* pBufferSize)\r
86 {\r
87         CWVBuffer               buf;\r
88         WV_IO_GUID_LIST *list;\r
89         DWORD                   bytes;\r
90         HRESULT                 hr;\r
91 \r
92         bytes = sizeof(WV_IO_GUID_LIST) + (DWORD) *pBufferSize;\r
93         list = (WV_IO_GUID_LIST *) buf.Get(bytes);\r
94         if (list == NULL) {\r
95                 return WV_NO_MEMORY;\r
96         }\r
97 \r
98         if (!WvDeviceIoControl(m_hFile, WV_IOCTL_GUID_QUERY, NULL, 0,\r
99                                                    list, bytes, &bytes, NULL)) {\r
100                 hr = HRESULT_FROM_WIN32(GetLastError());\r
101                 goto out;\r
102         }\r
103 \r
104         bytes = (DWORD) list->Count * sizeof NET64;\r
105         if (*pBufferSize >= bytes) {\r
106                 RtlCopyMemory(pGuidList, list->Guid, (size_t) bytes);\r
107         } else if (*pBufferSize > 0) {\r
108                 RtlCopyMemory(pGuidList, list->Guid, *pBufferSize);\r
109         }\r
110 \r
111         *pBufferSize = (size_t) bytes;\r
112         hr = WV_SUCCESS;\r
113 \r
114 out:\r
115         buf.Put();\r
116         return hr;\r
117 }\r
118 \r
119 STDMETHODIMP CWVProvider::\r
120 QueryDevice(NET64 Guid, WV_DEVICE_ATTRIBUTES* pAttributes)\r
121 {\r
122         IWVDevice *dev;\r
123         HRESULT hr;\r
124 \r
125         hr = OpenDevice(Guid, &dev);\r
126         if (FAILED(hr)) {\r
127                 goto out;\r
128         }\r
129         \r
130         hr = dev->Query(pAttributes);\r
131         dev->Release();\r
132 out:\r
133         return hr;\r
134 }\r
135 \r
136 STDMETHODIMP CWVProvider::\r
137 TranslateAddress(const SOCKADDR* pAddress, WV_DEVICE_ADDRESS* pDeviceAddress)\r
138 {\r
139         HANDLE hIbat;\r
140         IOCTL_IBAT_IP_TO_PORT_IN addr;\r
141         IBAT_PORT_RECORD port;\r
142         DWORD bytes;\r
143         HRESULT hr;\r
144 \r
145         hIbat = CreateFileW(IBAT_WIN32_NAME, GENERIC_READ | GENERIC_WRITE,\r
146                                                 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,\r
147                                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\r
148         if (hIbat == INVALID_HANDLE_VALUE) {\r
149                 return HRESULT_FROM_WIN32(GetLastError());\r
150         }\r
151 \r
152         addr.Version = IBAT_IOCTL_VERSION;\r
153         if (pAddress->sa_family == AF_INET) {\r
154                 addr.Address.IpVersion = 4;\r
155                 RtlCopyMemory(addr.Address.Address + 12,\r
156                                           &((SOCKADDR_IN *)pAddress)->sin_addr, 4);\r
157         } else {\r
158                 addr.Address.IpVersion = 6;\r
159                 RtlCopyMemory(addr.Address.Address,\r
160                                           &((SOCKADDR_IN6 *)pAddress)->sin6_addr, 16);\r
161         }\r
162 \r
163         if (DeviceIoControl(hIbat, IOCTL_IBAT_IP_TO_PORT,\r
164                                                 &addr, sizeof addr, &port, sizeof port, &bytes, NULL)) {\r
165                 hr = WV_SUCCESS;\r
166                 pDeviceAddress->DeviceGuid = port.CaGuid;\r
167                 pDeviceAddress->Pkey = port.PKey;\r
168                 pDeviceAddress->PortNumber = port.PortNum;\r
169         } else {\r
170                 hr = HRESULT_FROM_WIN32(GetLastError());\r
171         }\r
172 \r
173         CloseHandle(hIbat);\r
174         return hr;\r
175 }\r
176 \r
177 STDMETHODIMP CWVProvider::\r
178 OpenDevice(NET64 Guid, IWVDevice** ppDevice)\r
179 {\r
180         return CWVDevice::CreateInstance(this, Guid, ppDevice);\r
181 }\r
182 \r
183 STDMETHODIMP CWVProvider::\r
184 CreateConnectEndpoint(IWVConnectEndpoint** ppConnectEndpoint)\r
185 {\r
186         return CWVConnectEndpoint::CreateInstance(this, ppConnectEndpoint);\r
187 }\r
188 \r
189 STDMETHODIMP CWVProvider::\r
190 CreateDatagramEndpoint(IWVDatagramEndpoint** ppDatagramEndpoint)\r
191 {\r
192         return CWVDatagramEndpoint::CreateInstance(this, ppDatagramEndpoint);\r
193 }\r