[IBBUS] __iou/port_was_hibernated() change NTSTATUS --> ib_api_status_t to be consist...
[mirror/winof/.git] / core / winmad / user / wm_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 <windows.h>\r
31 #include <winioctl.h>\r
32 \r
33 #include "wm_memory.h"\r
34 #include "wm_provider.h"\r
35 #include "wm_ioctl.h"\r
36 \r
37 CWMProvider::CWMProvider()\r
38 {\r
39         InitializeCriticalSection(&m_CritSecRead);\r
40         InitializeCriticalSection(&m_CritSecWrite);\r
41         m_OverlapRead.hEvent = NULL;\r
42         m_OverlapWrite.hEvent = NULL;\r
43         m_nRef = 1;\r
44         m_hFile = INVALID_HANDLE_VALUE;\r
45         InterlockedIncrement(&WmRef);\r
46 }\r
47 \r
48 STDMETHODIMP CWMProvider::\r
49 Init(void)\r
50 {\r
51         m_OverlapRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
52         m_OverlapWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
53 \r
54         return (m_OverlapRead.hEvent != NULL && m_OverlapWrite.hEvent != NULL) ?\r
55                         NOERROR : E_OUTOFMEMORY;\r
56 }\r
57 \r
58 CWMProvider::~CWMProvider()\r
59 {\r
60         if (m_OverlapRead.hEvent != NULL) {\r
61                 CloseHandle(m_OverlapWrite.hEvent);\r
62         }\r
63         if (m_OverlapWrite.hEvent != NULL) {\r
64                 CloseHandle(m_OverlapWrite.hEvent);\r
65         }\r
66         CloseHandle(m_hFile);\r
67         InterlockedDecrement(&WmRef);\r
68 }\r
69 \r
70 STDMETHODIMP CWMProvider::\r
71 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)\r
72 {\r
73         if (riid != IID_IUnknown && riid != IID_IWMProvider) {\r
74                 *ppvObj = NULL;\r
75                 return E_NOINTERFACE;\r
76         }\r
77 \r
78         *ppvObj = this;\r
79         AddRef();\r
80         return NOERROR;\r
81 }\r
82 \r
83 STDMETHODIMP_(ULONG) CWMProvider::\r
84 AddRef(void)\r
85 {\r
86         return InterlockedIncrement(&m_nRef);\r
87 }\r
88 \r
89 STDMETHODIMP_(ULONG) CWMProvider::\r
90 Release(void)\r
91 {\r
92         ULONG ref;\r
93 \r
94         ref = (ULONG) InterlockedDecrement(&m_nRef);\r
95         if (ref == 0) {\r
96                 Delete();\r
97         }\r
98         return ref;\r
99 }\r
100 \r
101 STDMETHODIMP CWMProvider::\r
102 CancelOverlappedRequests(void)\r
103 {\r
104         DWORD   bytes;\r
105 \r
106         return WmDeviceIoControl(m_hFile, WM_IOCTL_CANCEL, NULL, 0,\r
107                                                          NULL, 0, &bytes, NULL) ?\r
108                                                          NOERROR : HRESULT_FROM_WIN32(GetLastError());\r
109 }\r
110 \r
111 STDMETHODIMP CWMProvider::\r
112 GetOverlappedResult(OVERLAPPED *pOverlapped,\r
113                                         DWORD *pNumberOfBytesTransferred, BOOL bWait)\r
114 {\r
115         ::GetOverlappedResult(m_hFile, pOverlapped, pNumberOfBytesTransferred, bWait);\r
116         return (HRESULT) pOverlapped->Internal;\r
117 }\r
118 \r
119 STDMETHODIMP_(HANDLE) CWMProvider::\r
120 GetFileHandle(void)\r
121 {\r
122         return m_hFile;\r
123 }\r
124 \r
125 STDMETHODIMP_(BOOL) CWMProvider::\r
126 WmDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,\r
127                                   LPVOID lpInBuffer, DWORD nInBufferSize,\r
128                                   LPVOID lpOutBuffer, DWORD nOutBufferSize,\r
129                                   LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)\r
130 {\r
131         BOOL ret;\r
132 \r
133         if (lpOverlapped == NULL) {\r
134                 EnterCriticalSection(&m_CritSecWrite);\r
135                 DeviceIoControl(hDevice, dwIoControlCode,\r
136                                                 lpInBuffer, nInBufferSize,\r
137                                                 lpOutBuffer, nOutBufferSize,\r
138                                                 lpBytesReturned, &m_OverlapWrite);\r
139                 ret = ::GetOverlappedResult(m_hFile, &m_OverlapWrite, lpBytesReturned, TRUE);\r
140                 LeaveCriticalSection(&m_CritSecWrite);\r
141         } else {\r
142                 ret = DeviceIoControl(hDevice, dwIoControlCode,\r
143                                                           lpInBuffer, nInBufferSize,\r
144                                                           lpOutBuffer, nOutBufferSize,\r
145                                                           lpBytesReturned, lpOverlapped);\r
146         }\r
147 \r
148         return ret;\r
149 }\r
150 \r
151 STDMETHODIMP_(BOOL) CWMProvider::\r
152 WmReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,\r
153                    LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)\r
154 {\r
155         BOOL ret;\r
156 \r
157         if (lpOverlapped == NULL) {\r
158                 EnterCriticalSection(&m_CritSecRead);\r
159                 ReadFile(hFile, lpBuffer, nNumberOfBytesToRead,\r
160                                  lpNumberOfBytesRead, &m_OverlapRead);\r
161                 ret = GetOverlappedResult(&m_OverlapRead, lpNumberOfBytesRead, TRUE);\r
162                 LeaveCriticalSection(&m_CritSecRead);\r
163         } else {\r
164                 ret = ReadFile(hFile, lpBuffer, nNumberOfBytesToRead,\r
165                                            lpNumberOfBytesRead, lpOverlapped);\r
166         }\r
167 \r
168         return ret;\r
169 }\r
170 \r
171 STDMETHODIMP_(BOOL) CWMProvider::\r
172 WmWriteFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberIfBytesToWrite,\r
173                         LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)\r
174 {\r
175         BOOL ret;\r
176 \r
177         if (lpOverlapped == NULL) {\r
178                 EnterCriticalSection(&m_CritSecWrite);\r
179                 WriteFile(hFile, lpBuffer, nNumberIfBytesToWrite,\r
180                                   lpNumberOfBytesWritten, &m_OverlapWrite);\r
181                 ret = GetOverlappedResult(&m_OverlapWrite, lpNumberOfBytesWritten, TRUE);\r
182                 LeaveCriticalSection(&m_CritSecWrite);\r
183         } else {\r
184                 ret = WriteFile(hFile, lpBuffer, nNumberIfBytesToWrite,\r
185                                                 lpNumberOfBytesWritten, lpOverlapped);\r
186         }\r
187 \r
188         return ret;\r
189 }\r
190 \r
191 STDMETHODIMP CWMProvider::\r
192 Register(WM_REGISTER *pAttributes, UINT64 *pId)\r
193 {\r
194         DWORD bytes;\r
195 \r
196         if (WmDeviceIoControl(m_hFile, WM_IOCTL_REGISTER,\r
197                                                   pAttributes, sizeof WM_REGISTER,\r
198                                                   pId, sizeof UINT64, &bytes, NULL)) {\r
199                 return NOERROR;\r
200         } else {\r
201                 return HRESULT_FROM_WIN32(GetLastError());\r
202         }\r
203 }\r
204 \r
205 STDMETHODIMP CWMProvider::\r
206 Deregister(UINT64 Id)\r
207 {\r
208         DWORD bytes;\r
209 \r
210         if (WmDeviceIoControl(m_hFile, WM_IOCTL_DEREGISTER,\r
211                                                   &Id, sizeof UINT64,\r
212                                                   NULL, 0, &bytes, NULL)) {\r
213                 return NOERROR;\r
214         } else {\r
215                 return HRESULT_FROM_WIN32(GetLastError());\r
216         }\r
217 }\r
218 \r
219 STDMETHODIMP CWMProvider::\r
220 Send(WM_MAD *pMad, OVERLAPPED *pOverlapped)\r
221 {\r
222         DWORD bytes;\r
223 \r
224         if (WmWriteFile(m_hFile, pMad, (DWORD) sizeof(WM_MAD) + pMad->Length,\r
225                                         &bytes, pOverlapped)) {\r
226                 return NOERROR;\r
227         } else {\r
228                 return HRESULT_FROM_WIN32(GetLastError());\r
229         }\r
230 }\r
231 \r
232 STDMETHODIMP CWMProvider::\r
233 Receive(WM_MAD *pMad, SIZE_T BufferSize, OVERLAPPED *pOverlapped)\r
234 {\r
235         DWORD bytes;\r
236 \r
237         if (WmReadFile(m_hFile, pMad, (DWORD) BufferSize, &bytes, pOverlapped)) {\r
238                 return NOERROR;\r
239         } else {\r
240                 return HRESULT_FROM_WIN32(GetLastError());\r
241         }\r
242 }\r