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)
9 /* INCLUDES ******************************************************************/
16 /* FUNCTIONS *****************************************************************/
28 return WSAAccept(s
, addr
, addrlen
, NULL
, 0);
37 IN CONST
struct sockaddr
*name
,
43 DPRINT("bind: %lx, %p, %lx\n", s
, name
, namelen
);
45 /* Check for WSAStartup */
46 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
48 /* Get the Socket Context */
49 if ((Socket
= WsSockGetSocket(s
)))
51 if (name
&& (namelen
>= sizeof(*name
)))
54 Status
= Socket
->Provider
->Service
.lpWSPBind(s
,
58 /* Deference the Socket Context */
59 WsSockDereference(Socket
);
61 /* Return Provider Value */
62 if (Status
== ERROR_SUCCESS
)
64 SetLastError(ErrorCode
);
68 /* If everything seemed fine, then the WSP call failed itself */
69 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
73 /* Deference the Socket Context */
74 WsSockDereference(Socket
);
76 /* name or namelen not valid */
77 ErrorCode
= WSAEFAULT
;
82 /* No Socket Context Found */
83 ErrorCode
= WSAENOTSOCK
;
87 /* Return with an Error */
88 SetLastError(ErrorCode
);
97 closesocket(IN SOCKET s
)
102 DPRINT("closesocket: %lx\n", s
);
104 /* Check for WSAStartup */
105 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
107 /* Get the Socket Context */
108 if ((Socket
= WsSockGetSocket(s
)))
111 Status
= Socket
->Provider
->Service
.lpWSPCloseSocket(s
, &ErrorCode
);
113 /* Check if this is a provider socket */
114 if ((Status
== ERROR_SUCCESS
) && (Socket
->IsProvider
))
116 /* Disassociate the handle */
117 if (WsSockDisassociateHandle(Socket
) == ERROR_SUCCESS
)
119 /* Deference the Socket Context */
120 WsSockDereference(Socket
);
123 /* Remove the last reference */
124 WsSockDereference(Socket
);
126 /* Return success if everything is OK */
127 if (ErrorCode
== ERROR_SUCCESS
)
129 SetLastError(ErrorCode
);
136 /* No Socket Context Found */
137 ErrorCode
= WSAENOTSOCK
;
141 /* Return with an Error */
142 SetLastError(ErrorCode
);
159 DPRINT("socket: %lx, %lx, %lx\n", af
, type
, protocol
);
162 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
165 SetLastError(ErrorCode
);
166 return INVALID_SOCKET
;
169 /* Check the current open type and use overlapped if it's default */
170 if (!Thread
->OpenType
) Flags
= WSA_FLAG_OVERLAPPED
;
172 /* Make the protocol negative if this is NETBIOS */
173 if ((af
== AF_NETBIOS
) && (protocol
> 0)) protocol
*= -1;
175 /* Now let WSA handle it */
176 return WSASocketW(af
, type
, protocol
, NULL
, 0, Flags
);
184 WPUCloseSocketHandle(IN SOCKET s
,
196 WPUCreateSocketHandle(IN DWORD dwCatalogEntryId
,
197 IN DWORD_PTR dwContext
,
209 WPUModifyIFSHandle(IN DWORD dwCatalogEntryId
,
210 IN SOCKET ProposedHandle
,
213 SOCKET Handle
= INVALID_SOCKET
;
214 DWORD ErrorCode
= ERROR_SUCCESS
;
217 PTCATALOG_ENTRY Entry
;
219 DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId
, ProposedHandle
);
221 /* Get the current process */
222 if ((Process
= WsGetProcess()))
224 /* Get the Transport Catalog */
225 if ((Catalog
= WsProcGetTCatalog(Process
)))
227 /* Get the entry for this ID */
228 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
231 /* Check for success */
232 if (ErrorCode
== ERROR_SUCCESS
)
234 /* Create a socket object */
235 if ((Socket
= WsSockAllocate()))
238 WsSockInitialize(Socket
, Entry
);
241 ErrorCode
= WsSockAssociateHandle(Socket
,
244 /* Check for success */
245 if (ErrorCode
== ERROR_SUCCESS
)
248 Handle
= ProposedHandle
;
249 *lpErrno
= ERROR_SUCCESS
;
254 WsSockDereference(Socket
);
255 *lpErrno
= ErrorCode
;
258 /* Dereference the extra count */
259 WsSockDereference(Socket
);
263 /* No memory to allocate a socket */
264 *lpErrno
= WSAENOBUFS
;
267 /* Dereference the catalog entry */
268 WsTcEntryDereference(Entry
);
272 /* Entry not found */
273 *lpErrno
= ErrorCode
;
278 /* Catalog not found */
279 *lpErrno
= WSANOTINITIALISED
;
284 /* Process not ready */
285 *lpErrno
= WSANOTINITIALISED
;
297 WPUQuerySocketHandleContext(IN SOCKET s
,
298 OUT PDWORD_PTR lpContext
,
310 WSAAccept(IN SOCKET s
,
312 IN OUT LPINT addrlen
,
313 IN LPCONDITIONPROC lpfnCondition
,
314 IN DWORD_PTR dwCallbackData
)
322 DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s
, addr
, addrlen
, lpfnCondition
);
325 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
327 /* Get the Socket Context */
328 if ((Socket
= WsSockGetSocket(s
)))
330 /* Get the old open type and set new one */
331 OpenType
= Thread
->OpenType
;
332 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
335 Status
= Socket
->Provider
->Service
.lpWSPAccept(s
,
341 /* Restore open type */
342 Thread
->OpenType
= OpenType
;
344 /* Deference the Socket Context */
345 WsSockDereference(Socket
);
347 /* Check if we got a valid socket */
348 if (Status
!= INVALID_SOCKET
)
350 /* Check if we got a new socket */
353 /* Add a new reference */
354 WsSockAddApiReference(Status
);
358 SetLastError(ErrorCode
);
364 /* No Socket Context Found */
365 ErrorCode
= WSAENOTSOCK
;
369 /* Return with an Error */
370 SetLastError(ErrorCode
);
371 return INVALID_SOCKET
;
379 WSAJoinLeaf(IN SOCKET s
,
380 IN CONST
struct sockaddr
*name
,
382 IN LPWSABUF lpCallerData
,
383 OUT LPWSABUF lpCalleeData
,
394 DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s
, name
, namelen
);
397 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
399 /* Get the Socket Context */
400 if ((Socket
= WsSockGetSocket(s
)))
402 /* Get the old open type and set new one */
403 OpenType
= Thread
->OpenType
;
404 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
407 Status
= Socket
->Provider
->Service
.lpWSPJoinLeaf(s
,
416 /* Restore open type */
417 Thread
->OpenType
= OpenType
;
419 /* Deference the Socket Context */
420 WsSockDereference(Socket
);
422 /* Check if we got a valid socket */
423 if (Status
!= INVALID_SOCKET
)
425 /* Check if we got a new socket */
428 /* Add a new reference */
429 WsSockAddApiReference(Status
);
433 SetLastError(ErrorCode
);
439 /* No Socket Context Found */
440 ErrorCode
= WSAENOTSOCK
;
444 /* Return with an Error */
445 SetLastError(ErrorCode
);
446 return INVALID_SOCKET
;
454 WSASocketA(IN INT af
,
457 IN LPWSAPROTOCOL_INFOA lpProtocolInfo
,
461 WSAPROTOCOL_INFOW ProtocolInfoW
;
462 LPWSAPROTOCOL_INFOW p
= &ProtocolInfoW
;
464 /* Convert Protocol Info to Wide */
468 memcpy(&ProtocolInfoW
,
470 sizeof(WSAPROTOCOL_INFOA
) - sizeof(CHAR
) * (WSAPROTOCOL_LEN
+ 1));
472 /* Convert the String */
473 MultiByteToWideChar(CP_ACP
,
475 lpProtocolInfo
->szProtocol
,
477 ProtocolInfoW
.szProtocol
,
478 sizeof(ProtocolInfoW
.szProtocol
) / sizeof(WCHAR
));
482 /* No Protocol Info Specified */
486 /* Call the Unicode Function */
487 return WSASocketW(af
,
500 WSASocketW(IN INT af
,
503 IN LPWSAPROTOCOL_INFOW lpProtocolInfo
,
512 PTCATALOG_ENTRY CatalogEntry
;
513 LPWSAPROTOCOL_INFOW ProtocolInfo
;
515 SOCKET Status
= INVALID_SOCKET
;
516 DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af
, type
, protocol
, lpProtocolInfo
);
519 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
522 SetLastError(ErrorCode
);
523 return INVALID_SOCKET
;
526 /* Get the catalog */
527 Catalog
= WsProcGetTCatalog(Process
);
529 /* Find a Provider for the Catalog ID */
532 /* Get the catalog ID */
533 CatalogId
= lpProtocolInfo
->dwCatalogEntryId
;
535 /* Get the Catalog Entry */
536 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
546 /* Get the Catalog Data from the Socket Info */
547 ErrorCode
= WsTcGetEntryFromTriplet(Catalog
,
555 /* Check for Success */
556 if (ErrorCode
== ERROR_SUCCESS
)
558 /* Use the default Protocol Info if none given */
559 ProtocolInfo
= lpProtocolInfo
? lpProtocolInfo
: &CatalogEntry
->ProtocolInfo
;
561 /* Save the open type and set new one */
562 OpenType
= Thread
->OpenType
;
563 Thread
->OpenType
= (dwFlags
& WSA_FLAG_OVERLAPPED
) ?
564 0 : SO_SYNCHRONOUS_NONALERT
;
566 /* Call the Provider to create the Socket */
567 Status
= CatalogEntry
->Provider
->Service
.lpWSPSocket(af
,
574 /* Restore open type */
575 Thread
->OpenType
= OpenType
;
577 /* Get the catalog ID now, and dereference */
578 CatalogId
= ProtocolInfo
->dwCatalogEntryId
;
579 WsTcEntryDereference(CatalogEntry
);
581 /* Did we fail with WSAEINPROGRESS and had no specific provider? */
582 if ((Status
== INVALID_SOCKET
) &&
583 (ErrorCode
== WSAEINPROGRESS
) &&
586 /* In that case, restart the lookup from this ID */
590 /* Check if we got a valid socket */
591 if (Status
!= INVALID_SOCKET
)
593 /* Add an API reference and return */
594 WsSockAddApiReference(Status
);
595 SetLastError(ErrorCode
);
600 /* Return with an Error */
601 SetLastError(ErrorCode
);
602 return INVALID_SOCKET
;