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(struct sockaddr
)))
54 Status
= Socket
->Provider
->Service
.lpWSPBind(s
,
58 /* Deference the Socket Context */
59 WsSockDereference(Socket
);
61 /* Return Provider Value */
62 if (Status
== ERROR_SUCCESS
) return Status
;
64 /* If everything seemed fine, then the WSP call failed itself */
65 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
69 /* name or namelen not valid */
70 ErrorCode
= WSAEFAULT
;
75 /* No Socket Context Found */
76 ErrorCode
= WSAENOTSOCK
;
80 /* Return with an Error */
81 SetLastError(ErrorCode
);
90 closesocket(IN SOCKET s
)
95 DPRINT("closesocket: %lx\n", s
);
97 /* Check for WSAStartup */
98 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
100 /* Get the Socket Context */
101 if ((Socket
= WsSockGetSocket(s
)))
104 Status
= Socket
->Provider
->Service
.lpWSPCloseSocket(s
, &ErrorCode
);
106 /* Check if this is a provider socket */
107 if ((Status
== ERROR_SUCCESS
) && (Socket
->IsProvider
))
109 /* Disassociate the handle */
110 if (WsSockDisassociateHandle(Socket
) == ERROR_SUCCESS
)
112 /* Deference the Socket Context */
113 WsSockDereference(Socket
);
116 /* Remove the last reference */
117 WsSockDereference(Socket
);
119 /* Return success if everything is OK */
120 if (ErrorCode
== ERROR_SUCCESS
) return ErrorCode
;
125 /* No Socket Context Found */
126 ErrorCode
= WSAENOTSOCK
;
130 /* Return with an Error */
131 SetLastError(ErrorCode
);
148 DPRINT("socket: %lx, %lx, %lx\n", af
, type
, protocol
);
151 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
154 SetLastError(ErrorCode
);
155 return INVALID_SOCKET
;
158 /* Check the current open type and use overlapped if it's default */
159 if (!Thread
->OpenType
) Flags
= WSA_FLAG_OVERLAPPED
;
161 /* Make the protocol negative if this is NETBIOS */
162 if ((af
== AF_NETBIOS
) && (protocol
> 0)) protocol
*= -1;
164 /* Now let WSA handle it */
165 return WSASocketW(af
, type
, protocol
, NULL
, 0, Flags
);
173 WPUCloseSocketHandle(IN SOCKET s
,
185 WPUCreateSocketHandle(IN DWORD dwCatalogEntryId
,
186 IN DWORD_PTR dwContext
,
198 WPUModifyIFSHandle(IN DWORD dwCatalogEntryId
,
199 IN SOCKET ProposedHandle
,
202 SOCKET Handle
= INVALID_SOCKET
;
203 DWORD ErrorCode
= ERROR_SUCCESS
;
206 PTCATALOG_ENTRY Entry
;
208 DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId
, ProposedHandle
);
210 /* Get the current process */
211 if ((Process
= WsGetProcess()))
213 /* Get the Transport Catalog */
214 if ((Catalog
= WsProcGetTCatalog(Process
)))
216 /* Get the entry for this ID */
217 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
220 /* Check for success */
221 if (ErrorCode
== ERROR_SUCCESS
)
223 /* Create a socket object */
224 if ((Socket
= WsSockAllocate()))
227 WsSockInitialize(Socket
, Entry
);
230 ErrorCode
= WsSockAssociateHandle(Socket
,
233 /* Check for success */
234 if (ErrorCode
== ERROR_SUCCESS
)
237 Handle
= ProposedHandle
;
238 *lpErrno
= ERROR_SUCCESS
;
243 WsSockDereference(Socket
);
244 *lpErrno
= ErrorCode
;
247 /* Dereference the extra count */
248 WsSockDereference(Socket
);
252 /* No memory to allocate a socket */
253 *lpErrno
= WSAENOBUFS
;
256 /* Dereference the catalog entry */
257 WsTcEntryDereference(Entry
);
261 /* Entry not found */
262 *lpErrno
= ErrorCode
;
267 /* Catalog not found */
268 *lpErrno
= WSANOTINITIALISED
;
273 /* Process not ready */
274 *lpErrno
= WSANOTINITIALISED
;
286 WPUQuerySocketHandleContext(IN SOCKET s
,
287 OUT PDWORD_PTR lpContext
,
299 WSAAccept(IN SOCKET s
,
301 IN OUT LPINT addrlen
,
302 IN LPCONDITIONPROC lpfnCondition
,
303 IN DWORD_PTR dwCallbackData
)
311 DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s
, addr
, addrlen
, lpfnCondition
);
314 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
316 /* Get the Socket Context */
317 if ((Socket
= WsSockGetSocket(s
)))
319 /* Get the old open type and set new one */
320 OpenType
= Thread
->OpenType
;
321 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
324 Status
= Socket
->Provider
->Service
.lpWSPAccept(s
,
330 /* Restore open type */
331 Thread
->OpenType
= OpenType
;
333 /* Deference the Socket Context */
334 WsSockDereference(Socket
);
336 /* Check if we got a valid socket */
337 if (Status
!= INVALID_SOCKET
)
339 /* Check if we got a new socket */
342 /* Add a new reference */
343 WsSockAddApiReference(Status
);
352 /* No Socket Context Found */
353 ErrorCode
= WSAENOTSOCK
;
357 /* Return with an Error */
358 SetLastError(ErrorCode
);
359 return INVALID_SOCKET
;
367 WSAJoinLeaf(IN SOCKET s
,
368 IN CONST
struct sockaddr
*name
,
370 IN LPWSABUF lpCallerData
,
371 OUT LPWSABUF lpCalleeData
,
382 DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s
, name
, namelen
);
385 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
387 /* Get the Socket Context */
388 if ((Socket
= WsSockGetSocket(s
)))
390 /* Get the old open type and set new one */
391 OpenType
= Thread
->OpenType
;
392 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
395 Status
= Socket
->Provider
->Service
.lpWSPJoinLeaf(s
,
404 /* Restore open type */
405 Thread
->OpenType
= OpenType
;
407 /* Deference the Socket Context */
408 WsSockDereference(Socket
);
410 /* Check if we got a valid socket */
411 if (Status
!= INVALID_SOCKET
)
413 /* Check if we got a new socket */
416 /* Add a new reference */
417 WsSockAddApiReference(Status
);
426 /* No Socket Context Found */
427 ErrorCode
= WSAENOTSOCK
;
431 /* Return with an Error */
432 SetLastError(ErrorCode
);
433 return INVALID_SOCKET
;
441 WSASocketA(IN INT af
,
444 IN LPWSAPROTOCOL_INFOA lpProtocolInfo
,
448 WSAPROTOCOL_INFOW ProtocolInfoW
;
449 LPWSAPROTOCOL_INFOW p
= &ProtocolInfoW
;
451 /* Convert Protocol Info to Wide */
455 memcpy(&ProtocolInfoW
,
457 sizeof(WSAPROTOCOL_INFOA
) - sizeof(CHAR
) * (WSAPROTOCOL_LEN
+ 1));
459 /* Convert the String */
460 MultiByteToWideChar(CP_ACP
,
462 lpProtocolInfo
->szProtocol
,
464 ProtocolInfoW
.szProtocol
,
465 sizeof(ProtocolInfoW
.szProtocol
) / sizeof(WCHAR
));
469 /* No Protocol Info Specified */
473 /* Call the Unicode Function */
474 return WSASocketW(af
,
487 WSASocketW(IN INT af
,
490 IN LPWSAPROTOCOL_INFOW lpProtocolInfo
,
499 PTCATALOG_ENTRY CatalogEntry
;
500 LPWSAPROTOCOL_INFOW ProtocolInfo
;
502 SOCKET Status
= INVALID_SOCKET
;
503 DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af
, type
, protocol
, lpProtocolInfo
);
506 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
509 SetLastError(ErrorCode
);
510 return INVALID_SOCKET
;
513 /* Get the catalog */
514 Catalog
= WsProcGetTCatalog(Process
);
516 /* Find a Provider for the Catalog ID */
519 /* Get the catalog ID */
520 CatalogId
= lpProtocolInfo
->dwCatalogEntryId
;
522 /* Get the Catalog Entry */
523 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
533 /* Get the Catalog Data from the Socket Info */
534 ErrorCode
= WsTcGetEntryFromTriplet(Catalog
,
542 /* Check for Success */
543 if (ErrorCode
== ERROR_SUCCESS
)
545 /* Use the default Protocol Info if none given */
546 ProtocolInfo
= lpProtocolInfo
? lpProtocolInfo
: &CatalogEntry
->ProtocolInfo
;
548 /* Save the open type and set new one */
549 OpenType
= Thread
->OpenType
;
550 Thread
->OpenType
= (dwFlags
& WSA_FLAG_OVERLAPPED
) ?
551 0 : SO_SYNCHRONOUS_NONALERT
;
553 /* Call the Provider to create the Socket */
554 Status
= CatalogEntry
->Provider
->Service
.lpWSPSocket(af
,
561 /* Restore open type */
562 Thread
->OpenType
= OpenType
;
564 /* Get the catalog ID now, and dereference */
565 CatalogId
= ProtocolInfo
->dwCatalogEntryId
;
566 WsTcEntryDereference(CatalogEntry
);
568 /* Did we fail with WSAEINPROGRESS and had no specific provider? */
569 if ((Status
== INVALID_SOCKET
) &&
570 (ErrorCode
== WSAEINPROGRESS
) &&
573 /* In that case, restart the lookup from this ID */
577 /* Check if we got a valid socket */
578 if (Status
!= INVALID_SOCKET
)
580 /* Add an API reference and return */
581 WsSockAddApiReference(Status
);
586 /* Return with an Error */
587 SetLastError(ErrorCode
);
588 return INVALID_SOCKET
;