Support unrar64.dll
[xy_vsfilter.git] / include / atl / atlspriv.inl
blob9693d33d5c67eca2d41b1353737dcb2d241a4d49
1 // This is a part of the Active Template Library.\r
2 // Copyright (C) Microsoft Corporation\r
3 // All rights reserved.\r
4 //\r
5 // This source code is only intended as a supplement to the\r
6 // Active Template Library Reference and related\r
7 // electronic documentation provided with the library.\r
8 // See these sources for detailed information regarding the\r
9 // Active Template Library product.\r
11 /////////////////////////////////////////////////////////////////////////////////\r
12 //\r
13 // ZEvtSyncSocket\r
14 // ************ This is an implementation only class ************\r
15 // Class ZEvtSyncSocket is a non-supported, implementation only \r
16 // class used by the ATL HTTP client class CAtlHttpClient. Do not\r
17 // use this class in your code. Use of this class is not supported by Microsoft.\r
18 //\r
19 /////////////////////////////////////////////////////////////////////////////////\r
21 #ifndef __ATLSPRIV_INL__\r
22 #define __ATLSPRIV_INL__\r
24 #pragma once\r
26 #pragma warning(push)\r
27 #pragma warning(disable:4312)\r
29 inline ZEvtSyncSocket::ZEvtSyncSocket() \r
30 {\r
31         m_dwCreateFlags = WSA_FLAG_OVERLAPPED;\r
32         m_hEventRead = m_hEventWrite = m_hEventConnect = NULL;\r
33         m_socket = INVALID_SOCKET;\r
34         m_bConnected = false;\r
35         m_dwLastError = 0;\r
36         m_dwSocketTimeout = ATL_SOCK_TIMEOUT;\r
37         g_HttpInit.Init();\r
38 }\r
40 inline ZEvtSyncSocket::~ZEvtSyncSocket() \r
41 {\r
42         Close();\r
43 }\r
45 inline ZEvtSyncSocket::operator SOCKET() \r
46 {\r
47         return m_socket;\r
48 }\r
50 inline void ZEvtSyncSocket::Close()\r
51 {\r
52         if (m_socket != INVALID_SOCKET)\r
53         {\r
54                 m_bConnected = false;\r
55                 closesocket(m_socket);\r
56                 m_socket = INVALID_SOCKET;\r
57                 Term();\r
58         }\r
59 }\r
61 inline void ZEvtSyncSocket::Term() \r
62 {\r
63         if (m_hEventRead)\r
64         {\r
65                 WSACloseEvent(m_hEventRead);\r
66                 m_hEventRead = NULL;\r
67         }\r
68         if (m_hEventWrite)\r
69         {\r
70                 WSACloseEvent(m_hEventWrite);\r
71                 m_hEventWrite = NULL;\r
72         }\r
73         if (m_hEventConnect)\r
74         {\r
75                 WSACloseEvent(m_hEventConnect);\r
76                 m_hEventConnect = NULL;\r
77         }\r
78         m_socket = INVALID_SOCKET;\r
79 }\r
81 inline bool ZEvtSyncSocket::Create(const ADDRINFOT* pAI, WORD wFlags)\r
82 {\r
83         return Create(pAI->ai_family, pAI->ai_socktype, pAI->ai_protocol, wFlags);\r
84 }\r
86 inline bool ZEvtSyncSocket::Create(int af, int st, int proto, WORD wFlags) \r
87 {\r
88         bool bRet = true;\r
89         if (m_socket != INVALID_SOCKET)\r
90         {\r
91                 m_dwLastError = WSAEALREADY;\r
92                 return false; // Must close this socket first\r
93         }\r
95         m_socket = WSASocket(af, st, proto, NULL, 0,\r
96                 wFlags | m_dwCreateFlags);\r
97         if (m_socket == INVALID_SOCKET)\r
98         {\r
99                 m_dwLastError = ::WSAGetLastError();\r
100                 bRet = false;\r
101         }\r
102         else\r
103                 bRet = Init(m_socket, NULL);\r
104         return bRet;\r
107 inline bool ZEvtSyncSocket::Connect(LPCTSTR szAddr, unsigned short nPort) throw()\r
109         if (m_bConnected)\r
110                 return true;\r
112         bool bRet = true;\r
113         CSocketAddr address;\r
114         // Find address information\r
115         if ((m_dwLastError = address.FindAddr(szAddr, nPort, 0, PF_UNSPEC, SOCK_STREAM, 0)) != ERROR_SUCCESS)\r
116         {\r
117                 bRet = false;\r
118         }\r
119         else\r
120         {\r
121                 bRet = Connect(address.GetAddrInfo());\r
122         }\r
123         return bRet;\r
126 inline bool ZEvtSyncSocket::Connect(const ADDRINFOT *pAI)\r
128         if (m_socket == INVALID_SOCKET && !Create(pAI))\r
129                 return false;\r
131         return Connect((SOCKADDR*)pAI->ai_addr, (int)pAI->ai_addrlen);\r
134 inline bool ZEvtSyncSocket::Connect(const SOCKADDR* psa, int len) \r
136         if (m_bConnected)\r
137                 return true; // already connected\r
139         DWORD dwLastError;\r
140         bool bRet = true;\r
142         // if you try to connect the socket without\r
143         // creating it first it's reasonable to automatically\r
144         // try the create for you.\r
145         if (m_socket == INVALID_SOCKET)\r
146                 return false;\r
148         if (WSAConnect(m_socket, \r
149                 psa, len,\r
150                 NULL, NULL, NULL, NULL))\r
151         {\r
152                 dwLastError = WSAGetLastError();\r
153                 if (dwLastError != WSAEWOULDBLOCK)\r
154                 {\r
155                         m_dwLastError = dwLastError;\r
156                         bRet = false;\r
157                 }\r
158                 else\r
159                 {\r
160                         dwLastError = WaitForSingleObject((HANDLE)m_hEventConnect, m_dwSocketTimeout);\r
161                         if (dwLastError == WAIT_OBJECT_0)\r
162                         {\r
163                                 // make sure there were no connection errors.\r
164                                 WSANETWORKEVENTS wse;\r
165                                 ZeroMemory(&wse, sizeof(wse));\r
166                                 WSAEnumNetworkEvents(m_socket, NULL, &wse);\r
167                                 if (wse.iErrorCode[FD_CONNECT_BIT]!=0)\r
168                                 {\r
169                                         m_dwLastError = (DWORD)(wse.iErrorCode[FD_CONNECT_BIT]);\r
170                                         bRet = false;\r
171                                 }\r
172                         }\r
173                         else\r
174                                 bRet = false;\r
175                 }\r
177         }\r
179         m_bConnected = bRet;\r
180         return bRet;\r
183 inline bool ZEvtSyncSocket::Write(WSABUF *pBuffers, int nCount, DWORD *pdwSize) \r
185         // if we aren't already connected we'll wait to see if the connect\r
186         // event happens\r
187         if (WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)m_hEventConnect , m_dwSocketTimeout))\r
188         {\r
189                 m_dwLastError = WSAENOTCONN;\r
190                 return false; // not connected\r
191         }\r
193         // make sure we aren't already writing\r
194         if (WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_hEventWrite, 0))\r
195         {\r
196                 m_dwLastError = WSAEINPROGRESS;\r
197                 return false; // another write on is blocking this socket\r
198         }\r
200         bool bRet = true;\r
201         *pdwSize = 0;\r
202         WSAOVERLAPPED o;\r
203         m_csWrite.Lock();\r
204         o.hEvent = m_hEventWrite;\r
205         WSAResetEvent(o.hEvent);\r
206         if (WSASend(m_socket, pBuffers, nCount, pdwSize, 0, &o, 0))\r
207         {       \r
208                 DWORD dwLastError = WSAGetLastError();\r
209                 if (dwLastError != WSA_IO_PENDING)\r
210                 {\r
211                         m_dwLastError = dwLastError;\r
212                         bRet = false;\r
213                 }\r
214         }\r
216         // wait for write to complete\r
217         if (bRet)\r
218         {\r
219                 if (WaitForSingleObject((HANDLE)m_hEventWrite, m_dwSocketTimeout) == WAIT_OBJECT_0)\r
220                 {\r
221                         DWORD dwFlags = 0;\r
222                         if (WSAGetOverlappedResult(m_socket, &o, pdwSize, FALSE, &dwFlags))\r
223                                 bRet = true;\r
224                         else\r
225                         {\r
226                                 m_dwLastError = ::GetLastError();\r
227                                 bRet = false;\r
228                         }\r
229                 }\r
230                 else\r
231                         bRet = false;\r
232         }\r
234         m_csWrite.Unlock();\r
235         return bRet;\r
238 inline bool ZEvtSyncSocket::Write(const unsigned char *pBuffIn, DWORD *pdwSize) \r
240         WSABUF buff;\r
241         buff.buf = (char*)pBuffIn;\r
242         buff.len = *pdwSize;\r
243         return Write(&buff, 1, pdwSize);\r
246 inline bool ZEvtSyncSocket::Read(const unsigned char *pBuff, DWORD *pdwSize) \r
248         // if we aren't already connected we'll wait to see if the connect\r
249         // event happens\r
250         if (WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)m_hEventConnect , m_dwSocketTimeout))\r
251         {\r
252                 m_dwLastError = WSAENOTCONN;\r
253                 return false; // not connected\r
254         }\r
256         if (WAIT_ABANDONED == WaitForSingleObject((HANDLE)m_hEventRead, 0))\r
257         {\r
258                 m_dwLastError = WSAEINPROGRESS;\r
259                 return false; // another write on is blocking this socket\r
260         }\r
262         bool bRet = true;\r
263         WSABUF buff;\r
264         buff.buf = (char*)pBuff;\r
265         buff.len = *pdwSize;\r
266         *pdwSize = 0;\r
267         DWORD dwFlags = 0;\r
268         WSAOVERLAPPED o;\r
269         ZeroMemory(&o, sizeof(o));\r
271         // protect against re-entrency\r
272         m_csRead.Lock();\r
273         o.hEvent = m_hEventRead;\r
274         WSAResetEvent(o.hEvent);\r
275         if (WSARecv(m_socket, &buff, 1, pdwSize, &dwFlags, &o, 0))\r
276         {\r
277                 DWORD dwLastError = WSAGetLastError();\r
278                 if (dwLastError != WSA_IO_PENDING)\r
279                 {\r
280                         m_dwLastError = dwLastError;\r
281                         bRet = false;\r
282                 }\r
283         }\r
285         // wait for the read to complete\r
286         if (bRet)\r
287         {\r
288                 if (WAIT_OBJECT_0 == WaitForSingleObject((HANDLE)o.hEvent, m_dwSocketTimeout))\r
289                 {\r
290                         dwFlags = 0;\r
291                         if (WSAGetOverlappedResult(m_socket, &o, pdwSize, FALSE, &dwFlags))\r
292                                 bRet = true;\r
293                         else\r
294                         {\r
295                                 m_dwLastError = ::GetLastError();\r
296                                 bRet = false;\r
297                         }\r
298                 }\r
299                 else\r
300                         bRet = false;\r
301         }\r
303         m_csRead.Unlock();\r
304         return bRet;\r
307 inline bool ZEvtSyncSocket::Init(SOCKET hSocket, void * /*pData=NULL*/) \r
309         ATLASSERT(hSocket != INVALID_SOCKET);\r
311         if (hSocket == INVALID_SOCKET)\r
312         {\r
313                 m_dwLastError = WSAENOTSOCK;\r
314                 return false;\r
315         }\r
317         m_socket = hSocket;\r
319         // Allocate Events. On error, any open event handles will be closed\r
320         // in the destructor\r
321         if (NULL != (m_hEventRead = WSACreateEvent()))\r
322                 if (NULL != (m_hEventWrite = WSACreateEvent()))\r
323                         if (NULL != (m_hEventConnect = WSACreateEvent()))\r
324         {\r
325                 if (!WSASetEvent(m_hEventWrite) || !WSASetEvent(m_hEventRead))\r
326                 {\r
327                         m_dwLastError = ::GetLastError();\r
328                         return false;\r
329                 }\r
331                 if (SOCKET_ERROR != WSAEventSelect(m_socket, m_hEventRead, FD_READ))\r
332                         if (SOCKET_ERROR != WSAEventSelect(m_socket, m_hEventWrite, FD_WRITE))\r
333                                 if (SOCKET_ERROR != WSAEventSelect(m_socket, m_hEventConnect, FD_CONNECT))\r
334                                         return true;\r
335         }\r
336         m_dwLastError = ::GetLastError();\r
337         return false;\r
340 inline DWORD ZEvtSyncSocket::GetSocketTimeout() throw()\r
342         return m_dwSocketTimeout;\r
345 inline DWORD ZEvtSyncSocket::SetSocketTimeout(DWORD dwNewTimeout) throw()\r
347         DWORD dwOldTimeout = m_dwSocketTimeout;\r
348         m_dwSocketTimeout = dwNewTimeout;\r
349         return dwOldTimeout;\r
352 inline bool ZEvtSyncSocket::SupportsScheme(ATL_URL_SCHEME scheme) throw()\r
354         // default only supports HTTP\r
355         return scheme == ATL_URL_SCHEME_HTTP ? true : false;\r
359 #pragma warning(pop)\r
361 #endif // __ATLSPRIV_INL__\r