ReactOS  0.4.13-dev-100-gc8611ae
socklife.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS WinSock 2 API
4  * FILE: dll/win32/ws2_32_new/src/socklife.c
5  * PURPOSE: Socket Lifetime Support
6  * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ws2_32.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* FUNCTIONS *****************************************************************/
17 
18 /*
19  * @implemented
20  */
21 SOCKET
22 WSAAPI
25  OUT INT FAR* addrlen)
26 {
27  /* Let WSA do it */
28  return WSAAccept(s, addr, addrlen, NULL, 0);
29 }
30 
31 /*
32  * @implemented
33  */
34 INT
35 WSAAPI
37  IN CONST struct sockaddr *name,
38  IN INT namelen)
39 {
40  PWSSOCKET Socket;
41  INT Status;
42  INT ErrorCode;
43  DPRINT("bind: %lx, %p, %lx\n", s, name, namelen);
44 
45  /* Check for WSAStartup */
47  {
48  /* Get the Socket Context */
49  if ((Socket = WsSockGetSocket(s)))
50  {
51  if (name && (namelen >= sizeof(*name)))
52  {
53  /* Make the call */
54  Status = Socket->Provider->Service.lpWSPBind(s,
55  name,
56  namelen,
57  &ErrorCode);
58  /* Deference the Socket Context */
59  WsSockDereference(Socket);
60 
61  /* Return Provider Value */
62  if (Status == ERROR_SUCCESS) return Status;
63 
64  /* If everything seemed fine, then the WSP call failed itself */
66  }
67  else
68  {
69  /* Deference the Socket Context */
70  WsSockDereference(Socket);
71 
72  /* name or namelen not valid */
74  }
75  }
76  else
77  {
78  /* No Socket Context Found */
80  }
81  }
82 
83  /* Return with an Error */
85  return SOCKET_ERROR;
86 }
87 
88 /*
89  * @implemented
90  */
91 INT
92 WSAAPI
94 {
95  PWSSOCKET Socket;
96  INT Status;
97  INT ErrorCode;
98  DPRINT("closesocket: %lx\n", s);
99 
100  /* Check for WSAStartup */
102  {
103  /* Get the Socket Context */
104  if ((Socket = WsSockGetSocket(s)))
105  {
106  /* Make the call */
108 
109  /* Check if this is a provider socket */
110  if ((Status == ERROR_SUCCESS) && (Socket->IsProvider))
111  {
112  /* Disassociate the handle */
114  {
115  /* Deference the Socket Context */
116  WsSockDereference(Socket);
117  }
118 
119  /* Remove the last reference */
120  WsSockDereference(Socket);
121 
122  /* Return success if everything is OK */
123  if (ErrorCode == ERROR_SUCCESS) return ErrorCode;
124  }
125  }
126  else
127  {
128  /* No Socket Context Found */
130  }
131  }
132 
133  /* Return with an Error */
135  return SOCKET_ERROR;
136 }
137 
138 /*
139  * @implemented
140  */
141 SOCKET
142 WSAAPI
144  IN INT type,
145  IN INT protocol)
146 {
149  DWORD Flags = 0;
150  INT ErrorCode;
151  DPRINT("socket: %lx, %lx, %lx\n", af, type, protocol);
152 
153  /* Enter prolog */
155  {
156  /* Fail here */
158  return INVALID_SOCKET;
159  }
160 
161  /* Check the current open type and use overlapped if it's default */
162  if (!Thread->OpenType) Flags = WSA_FLAG_OVERLAPPED;
163 
164  /* Make the protocol negative if this is NETBIOS */
165  if ((af == AF_NETBIOS) && (protocol > 0)) protocol *= -1;
166 
167  /* Now let WSA handle it */
168  return WSASocketW(af, type, protocol, NULL, 0, Flags);
169 }
170 
171 /*
172  * @unimplemented
173  */
174 INT
175 WSPAPI
177  OUT LPINT lpErrno)
178 {
180  return 0;
181 }
182 
183 /*
184  * @unimplemented
185  */
186 SOCKET
187 WSPAPI
188 WPUCreateSocketHandle(IN DWORD dwCatalogEntryId,
189  IN DWORD_PTR dwContext,
190  OUT LPINT lpErrno)
191 {
193  return (SOCKET)0;
194 }
195 
196 /*
197  * @implemented
198  */
199 SOCKET
200 WSPAPI
201 WPUModifyIFSHandle(IN DWORD dwCatalogEntryId,
202  IN SOCKET ProposedHandle,
203  OUT LPINT lpErrno)
204 {
208  PTCATALOG Catalog;
210  PWSSOCKET Socket;
211  DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId, ProposedHandle);
212 
213  /* Get the current process */
214  if ((Process = WsGetProcess()))
215  {
216  /* Get the Transport Catalog */
217  if ((Catalog = WsProcGetTCatalog(Process)))
218  {
219  /* Get the entry for this ID */
221  dwCatalogEntryId,
222  &Entry);
223  /* Check for success */
224  if (ErrorCode == ERROR_SUCCESS)
225  {
226  /* Create a socket object */
227  if ((Socket = WsSockAllocate()))
228  {
229  /* Initialize it */
230  WsSockInitialize(Socket, Entry);
231 
232  /* Associate it */
234  ProposedHandle,
235  TRUE);
236  /* Check for success */
237  if (ErrorCode == ERROR_SUCCESS)
238  {
239  /* Return */
240  Handle = ProposedHandle;
241  *lpErrno = ERROR_SUCCESS;
242  }
243  else
244  {
245  /* Fail */
246  WsSockDereference(Socket);
247  *lpErrno = ErrorCode;
248  }
249 
250  /* Dereference the extra count */
251  WsSockDereference(Socket);
252  }
253  else
254  {
255  /* No memory to allocate a socket */
256  *lpErrno = WSAENOBUFS;
257  }
258 
259  /* Dereference the catalog entry */
261  }
262  else
263  {
264  /* Entry not found */
265  *lpErrno = ErrorCode;
266  }
267  }
268  else
269  {
270  /* Catalog not found */
271  *lpErrno = WSANOTINITIALISED;
272  }
273  }
274  else
275  {
276  /* Process not ready */
277  *lpErrno = WSANOTINITIALISED;
278  }
279 
280  /* Return */
281  return Handle;
282 }
283 
284 /*
285  * @unimplemented
286  */
287 INT
288 WSPAPI
290  OUT PDWORD_PTR lpContext,
291  OUT LPINT lpErrno)
292 {
294  return 0;
295 }
296 
297 /*
298  * @implemented
299  */
300 SOCKET
301 WSAAPI
304  IN OUT LPINT addrlen,
305  IN LPCONDITIONPROC lpfnCondition,
306  IN DWORD_PTR dwCallbackData)
307 {
310  PWSSOCKET Socket;
311  DWORD OpenType;
312  INT ErrorCode;
313  SOCKET Status;
314  DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s, addr, addrlen, lpfnCondition);
315 
316  /* Enter prolog */
318  {
319  /* Get the Socket Context */
320  if ((Socket = WsSockGetSocket(s)))
321  {
322  /* Get the old open type and set new one */
323  OpenType = Thread->OpenType;
324  Thread->OpenType = Socket->Overlapped ? 0 : SO_SYNCHRONOUS_NONALERT;
325 
326  /* Make the call */
327  Status = Socket->Provider->Service.lpWSPAccept(s,
328  addr,
329  addrlen,
330  lpfnCondition,
331  dwCallbackData,
332  &ErrorCode);
333  /* Restore open type */
334  Thread->OpenType = OpenType;
335 
336  /* Deference the Socket Context */
337  WsSockDereference(Socket);
338 
339  /* Check if we got a valid socket */
340  if (Status != INVALID_SOCKET)
341  {
342  /* Check if we got a new socket */
343  if (Status != s)
344  {
345  /* Add a new reference */
347  }
348 
349  /* Return */
350  return Status;
351  }
352  }
353  else
354  {
355  /* No Socket Context Found */
357  }
358  }
359 
360  /* Return with an Error */
362  return INVALID_SOCKET;
363 }
364 
365 /*
366  * @implemented
367  */
368 SOCKET
369 WSAAPI
371  IN CONST struct sockaddr *name,
372  IN INT namelen,
373  IN LPWSABUF lpCallerData,
374  OUT LPWSABUF lpCalleeData,
375  IN LPQOS lpSQOS,
376  IN LPQOS lpGQOS,
377  IN DWORD dwFlags)
378 {
381  PWSSOCKET Socket;
382  DWORD OpenType;
383  INT ErrorCode;
384  SOCKET Status;
385  DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s, name, namelen);
386 
387  /* Enter prolog */
389  {
390  /* Get the Socket Context */
391  if ((Socket = WsSockGetSocket(s)))
392  {
393  /* Get the old open type and set new one */
394  OpenType = Thread->OpenType;
395  Thread->OpenType = Socket->Overlapped ? 0 : SO_SYNCHRONOUS_NONALERT;
396 
397  /* Make the call */
399  name,
400  namelen,
401  lpCallerData,
402  lpCalleeData,
403  lpSQOS,
404  lpGQOS,
405  dwFlags,
406  &ErrorCode);
407  /* Restore open type */
408  Thread->OpenType = OpenType;
409 
410  /* Deference the Socket Context */
411  WsSockDereference(Socket);
412 
413  /* Check if we got a valid socket */
414  if (Status != INVALID_SOCKET)
415  {
416  /* Check if we got a new socket */
417  if (Status != s)
418  {
419  /* Add a new reference */
421  }
422 
423  /* Return */
424  return Status;
425  }
426  }
427  else
428  {
429  /* No Socket Context Found */
431  }
432  }
433 
434  /* Return with an Error */
436  return INVALID_SOCKET;
437 }
438 
439 /*
440  * @implemented
441  */
442 SOCKET
443 WSAAPI
445  IN INT type,
446  IN INT protocol,
447  IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
448  IN GROUP g,
449  IN DWORD dwFlags)
450 {
451  WSAPROTOCOL_INFOW ProtocolInfoW;
452  LPWSAPROTOCOL_INFOW p = &ProtocolInfoW;
453 
454  /* Convert Protocol Info to Wide */
455  if (lpProtocolInfo)
456  {
457  /* Copy the Data */
458  memcpy(&ProtocolInfoW,
459  lpProtocolInfo,
460  sizeof(WSAPROTOCOL_INFOA) - sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));
461 
462  /* Convert the String */
464  0,
465  lpProtocolInfo->szProtocol,
466  -1,
467  ProtocolInfoW.szProtocol,
468  sizeof(ProtocolInfoW.szProtocol) / sizeof(WCHAR));
469  }
470  else
471  {
472  /* No Protocol Info Specified */
473  p = NULL;
474  }
475 
476  /* Call the Unicode Function */
477  return WSASocketW(af,
478  type,
479  protocol,
480  p,
481  g,
482  dwFlags);
483 }
484 
485 /*
486  * @implemented
487  */
488 SOCKET
489 WSAAPI
491  IN INT type,
492  IN INT protocol,
493  IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
494  IN GROUP g,
495  IN DWORD dwFlags)
496 {
499  INT ErrorCode;
500  PTCATALOG Catalog;
501  DWORD CatalogId;
502  PTCATALOG_ENTRY CatalogEntry;
503  LPWSAPROTOCOL_INFOW ProtocolInfo;
504  DWORD OpenType;
506  DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af, type, protocol, lpProtocolInfo);
507 
508  /* Enter prolog */
510  {
511  /* Fail now */
513  return INVALID_SOCKET;
514  }
515 
516  /* Get the catalog */
517  Catalog = WsProcGetTCatalog(Process);
518 
519  /* Find a Provider for the Catalog ID */
520  if (lpProtocolInfo)
521  {
522  /* Get the catalog ID */
523  CatalogId = lpProtocolInfo->dwCatalogEntryId;
524 
525  /* Get the Catalog Entry */
527  CatalogId,
528  &CatalogEntry);
529  }
530  else
531  {
532  /* No ID */
533  CatalogId = 0;
534 
535 DoLookup:
536  /* Get the Catalog Data from the Socket Info */
538  af,
539  type,
540  protocol,
541  CatalogId,
542  &CatalogEntry);
543  }
544 
545  /* Check for Success */
546  if (ErrorCode == ERROR_SUCCESS)
547  {
548  /* Use the default Protocol Info if none given */
549  ProtocolInfo = lpProtocolInfo ? lpProtocolInfo : &CatalogEntry->ProtocolInfo;
550 
551  /* Save the open type and set new one */
552  OpenType = Thread->OpenType;
553  Thread->OpenType = (dwFlags & WSA_FLAG_OVERLAPPED) ?
555 
556  /* Call the Provider to create the Socket */
557  Status = CatalogEntry->Provider->Service.lpWSPSocket(af,
558  type,
559  protocol,
560  ProtocolInfo,
561  g,
562  dwFlags,
563  &ErrorCode);
564  /* Restore open type */
565  Thread->OpenType = OpenType;
566 
567  /* Get the catalog ID now, and dereference */
568  CatalogId = ProtocolInfo->dwCatalogEntryId;
569  WsTcEntryDereference(CatalogEntry);
570 
571  /* Did we fail with WSAEINPROGRESS and had no specific provider? */
572  if ((Status == INVALID_SOCKET) &&
573  (ErrorCode == WSAEINPROGRESS) &&
574  !(lpProtocolInfo))
575  {
576  /* In that case, restart the lookup from this ID */
577  goto DoLookup;
578  }
579 
580  /* Check if we got a valid socket */
581  if (Status != INVALID_SOCKET)
582  {
583  /* Add an API reference and return */
585  return Status;
586  }
587  }
588 
589  /* Return with an Error */
591  return INVALID_SOCKET;
592 }
SOCKET WSPAPI WPUCreateSocketHandle(IN DWORD dwCatalogEntryId, IN DWORD_PTR dwContext, OUT LPINT lpErrno)
Definition: socklife.c:188
#define WSAENOTSOCK
Definition: winerror.h:1951
#define SOCKET_ERROR
Definition: winsock.h:333
BOOLEAN IsProvider
Definition: ws2_32p.h:203
#define IN
Definition: typedefs.h:38
int(CALLBACK * LPCONDITIONPROC)(IN LPWSABUF lpCallerId, IN LPWSABUF lpCallerData, IN OUT LPQOS lpSQOS, IN OUT LPQOS lpGQOS, IN LPWSABUF lpCalleeId, IN LPWSABUF lpCalleeData, OUT GROUP FAR *g, IN DWORD_PTR dwCallbackData)
Definition: winsock2.h:711
INT WSPAPI WPUQuerySocketHandleContext(IN SOCKET s, OUT PDWORD_PTR lpContext, OUT LPINT lpErrno)
Definition: socklife.c:289
#define WSAPROTOCOL_LEN
Definition: winsock2.h:428
#define TRUE
Definition: types.h:120
BOOLEAN Overlapped
Definition: ws2_32p.h:201
#define WSAEFAULT
Definition: winerror.h:1945
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4418
Definition: ws2_32p.h:85
#define WSA_FLAG_OVERLAPPED
Definition: winsock2.h:466
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
#define ERROR_SUCCESS
Definition: deptool.c:10
struct _Entry Entry
Definition: kefuncs.h:640
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
#define CP_ACP
Definition: compat.h:99
char CHAR
Definition: xmlstorage.h:175
SOCKET WSAAPI WSASocketA(IN INT af, IN INT type, IN INT protocol, IN LPWSAPROTOCOL_INFOA lpProtocolInfo, IN GROUP g, IN DWORD dwFlags)
Definition: socklife.c:444
SOCKET WSPAPI WPUModifyIFSHandle(IN DWORD dwCatalogEntryId, IN SOCKET ProposedHandle, OUT LPINT lpErrno)
Definition: socklife.c:201
LPWSPJOINLEAF lpWSPJoinLeaf
Definition: ws2spi.h:478
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
PWSSOCKET WSAAPI WsSockGetSocket(IN SOCKET Handle)
Definition: dsocket.c:140
DWORD WSAAPI WsTcGetEntryFromTriplet(IN PTCATALOG TCatalog, IN INT AddressFamily, IN INT SocketType, IN INT Protocol, IN DWORD StartId, IN PTCATALOG_ENTRY *CatalogEntry)
Definition: dcatalog.c:480
DWORD WSAAPI WsTcGetEntryFromCatalogEntryId(IN PTCATALOG TCatalog, IN DWORD CatalogEntryId, IN PTCATALOG_ENTRY *CatalogEntry)
Definition: dcatalog.c:434
#define AF_NETBIOS
Definition: winsock.h:363
PTPROVIDER Provider
Definition: ws2_32p.h:89
#define NO_ERROR
Definition: dderror.h:5
GLint namelen
Definition: glext.h:7232
#define WSAEINPROGRESS
Definition: winerror.h:1949
int32_t INT
Definition: typedefs.h:56
WSPPROC_TABLE Service
Definition: ws2_32p.h:80
VOID WSAAPI WsSockDereference(IN PWSSOCKET Socket)
Definition: dsocket.c:205
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
DWORD dwCatalogEntryId
Definition: winsock2.h:686
LPWSPCLOSESOCKET lpWSPCloseSocket
Definition: ws2spi.h:467
#define FAR
Definition: guiddef.h:36
SOCKET WSAAPI WSASocketW(IN INT af, IN INT type, IN INT protocol, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, IN GROUP g, IN DWORD dwFlags)
Definition: socklife.c:490
INT WSAAPI WsSockInitialize(IN PWSSOCKET Socket, IN PTCATALOG_ENTRY CatalogEntry)
Definition: dsocket.c:67
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE PWSPROCESS WsGetProcess(VOID)
Definition: ws2_32p.h:885
PWSSOCKET WSAAPI WsSockAllocate(VOID)
Definition: dsocket.c:48
void DPRINT(...)
Definition: polytest.cpp:61
INT WSAAPI WsSockDisassociateHandle(IN PWSSOCKET Socket)
Definition: dsocket.c:217
INT WSPAPI WPUCloseSocketHandle(IN SOCKET s, OUT LPINT lpErrno)
Definition: socklife.c:176
_In_ HANDLE Handle
Definition: extypes.h:390
GLboolean GLboolean g
Definition: glext.h:6204
#define WSANOTINITIALISED
Definition: winerror.h:1987
VOID WSAAPI WsTcEntryDereference(IN PTCATALOG_ENTRY CatalogEntry)
Definition: dcatitem.c:51
#define INVALID_SOCKET
Definition: winsock.h:332
__wchar_t WCHAR
Definition: xmlstorage.h:180
PTPROVIDER Provider
Definition: ws2_32p.h:199
unsigned int GROUP
Definition: winsock2.h:640
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define SetLastError(x)
Definition: compat.h:409
ULONG_PTR * PDWORD_PTR
Definition: basetsd.h:184
SOCKET WSAAPI WSAJoinLeaf(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen, IN LPWSABUF lpCallerData, OUT LPWSABUF lpCalleeData, IN LPQOS lpSQOS, IN LPQOS lpGQOS, IN DWORD dwFlags)
Definition: socklife.c:370
INT WSAAPI WsApiProlog(OUT PWSPROCESS *Process, OUT PWSTHREAD *Thread)
Definition: wsautil.c:91
WSAPROTOCOL_INFOW ProtocolInfo
Definition: ws2_32p.h:91
INT WSAAPI WsSockAssociateHandle(IN PWSSOCKET Socket, IN SOCKET Handle, IN BOOLEAN IsProvider)
Definition: dsocket.c:225
GLenum const GLvoid * addr
Definition: glext.h:9621
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
INT WSAAPI WsSockAddApiReference(IN SOCKET Handle)
Definition: dsocket.c:159
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLdouble s
Definition: gl.h:2039
uint32_t DWORD_PTR
Definition: typedefs.h:63
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
Status
Definition: gdiplustypes.h:24
#define WSASYSCALLFAILURE
Definition: winerror.h:1994
SOCKET WSAAPI WSAAccept(IN SOCKET s, OUT LPSOCKADDR addr, IN OUT LPINT addrlen, IN LPCONDITIONPROC lpfnCondition, IN DWORD_PTR dwCallbackData)
Definition: socklife.c:302
LPWSPACCEPT lpWSPAccept
Definition: ws2spi.h:461
#define WSAAPI
Definition: winsock2.h:584
LPWSPBIND lpWSPBind
Definition: ws2spi.h:464
#define MultiByteToWideChar
Definition: compat.h:100
LPWSPSOCKET lpWSPSocket
Definition: ws2spi.h:489
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
Definition: name.c:36
#define OUT
Definition: typedefs.h:39
INT WSAAPI closesocket(IN SOCKET s)
Definition: socklife.c:93
#define UNIMPLEMENTED
Definition: debug.h:114
WCHAR szProtocol[WSAPROTOCOL_LEN+1]
Definition: winsock2.h:699
UINT_PTR SOCKET
Definition: winsock.h:47
GLfloat GLfloat p
Definition: glext.h:8902
FORCEINLINE DWORD WsQuickProlog(VOID)
Definition: ws2_32p.h:892
#define WSAENOBUFS
Definition: winerror.h:1968
#define CONST
Definition: pedump.c:81
base of all file and directory entries
Definition: entries.h:82
PTCATALOG WSAAPI WsProcGetTCatalog(IN PWSPROCESS Process)
Definition: dprocess.c:150
int * LPINT
Definition: windef.h:178
#define WSPAPI
Definition: ws2spi.h:39