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
) return Status
;
64 /* If everything seemed fine, then the WSP call failed itself */
65 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
69 /* Deference the Socket Context */
70 WsSockDereference(Socket
);
72 /* name or namelen not valid */
73 ErrorCode
= WSAEFAULT
;
78 /* No Socket Context Found */
79 ErrorCode
= WSAENOTSOCK
;
83 /* Return with an Error */
84 SetLastError(ErrorCode
);
93 closesocket(IN SOCKET s
)
98 DPRINT("closesocket: %lx\n", s
);
100 /* Check for WSAStartup */
101 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
103 /* Get the Socket Context */
104 if ((Socket
= WsSockGetSocket(s
)))
107 Status
= Socket
->Provider
->Service
.lpWSPCloseSocket(s
, &ErrorCode
);
109 /* Check if this is a provider socket */
110 if ((Status
== ERROR_SUCCESS
) && (Socket
->IsProvider
))
112 /* Disassociate the handle */
113 if (WsSockDisassociateHandle(Socket
) == ERROR_SUCCESS
)
115 /* Deference the Socket Context */
116 WsSockDereference(Socket
);
119 /* Remove the last reference */
120 WsSockDereference(Socket
);
122 /* Return success if everything is OK */
123 if (ErrorCode
== ERROR_SUCCESS
) return ErrorCode
;
128 /* No Socket Context Found */
129 ErrorCode
= WSAENOTSOCK
;
133 /* Return with an Error */
134 SetLastError(ErrorCode
);
151 DPRINT("socket: %lx, %lx, %lx\n", af
, type
, protocol
);
154 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
157 SetLastError(ErrorCode
);
158 return INVALID_SOCKET
;
161 /* Check the current open type and use overlapped if it's default */
162 if (!Thread
->OpenType
) Flags
= WSA_FLAG_OVERLAPPED
;
164 /* Make the protocol negative if this is NETBIOS */
165 if ((af
== AF_NETBIOS
) && (protocol
> 0)) protocol
*= -1;
167 /* Now let WSA handle it */
168 return WSASocketW(af
, type
, protocol
, NULL
, 0, Flags
);
176 WPUCloseSocketHandle(IN SOCKET s
,
188 WPUCreateSocketHandle(IN DWORD dwCatalogEntryId
,
189 IN DWORD_PTR dwContext
,
201 WPUModifyIFSHandle(IN DWORD dwCatalogEntryId
,
202 IN SOCKET ProposedHandle
,
205 SOCKET Handle
= INVALID_SOCKET
;
206 DWORD ErrorCode
= ERROR_SUCCESS
;
209 PTCATALOG_ENTRY Entry
;
211 DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId
, ProposedHandle
);
213 /* Get the current process */
214 if ((Process
= WsGetProcess()))
216 /* Get the Transport Catalog */
217 if ((Catalog
= WsProcGetTCatalog(Process
)))
219 /* Get the entry for this ID */
220 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
223 /* Check for success */
224 if (ErrorCode
== ERROR_SUCCESS
)
226 /* Create a socket object */
227 if ((Socket
= WsSockAllocate()))
230 WsSockInitialize(Socket
, Entry
);
233 ErrorCode
= WsSockAssociateHandle(Socket
,
236 /* Check for success */
237 if (ErrorCode
== ERROR_SUCCESS
)
240 Handle
= ProposedHandle
;
241 *lpErrno
= ERROR_SUCCESS
;
246 WsSockDereference(Socket
);
247 *lpErrno
= ErrorCode
;
250 /* Dereference the extra count */
251 WsSockDereference(Socket
);
255 /* No memory to allocate a socket */
256 *lpErrno
= WSAENOBUFS
;
259 /* Dereference the catalog entry */
260 WsTcEntryDereference(Entry
);
264 /* Entry not found */
265 *lpErrno
= ErrorCode
;
270 /* Catalog not found */
271 *lpErrno
= WSANOTINITIALISED
;
276 /* Process not ready */
277 *lpErrno
= WSANOTINITIALISED
;
289 WPUQuerySocketHandleContext(IN SOCKET s
,
290 OUT PDWORD_PTR lpContext
,
302 WSAAccept(IN SOCKET s
,
304 IN OUT LPINT addrlen
,
305 IN LPCONDITIONPROC lpfnCondition
,
306 IN DWORD_PTR dwCallbackData
)
314 DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s
, addr
, addrlen
, lpfnCondition
);
317 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
319 /* Get the Socket Context */
320 if ((Socket
= WsSockGetSocket(s
)))
322 /* Get the old open type and set new one */
323 OpenType
= Thread
->OpenType
;
324 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
327 Status
= Socket
->Provider
->Service
.lpWSPAccept(s
,
333 /* Restore open type */
334 Thread
->OpenType
= OpenType
;
336 /* Deference the Socket Context */
337 WsSockDereference(Socket
);
339 /* Check if we got a valid socket */
340 if (Status
!= INVALID_SOCKET
)
342 /* Check if we got a new socket */
345 /* Add a new reference */
346 WsSockAddApiReference(Status
);
355 /* No Socket Context Found */
356 ErrorCode
= WSAENOTSOCK
;
360 /* Return with an Error */
361 SetLastError(ErrorCode
);
362 return INVALID_SOCKET
;
370 WSAJoinLeaf(IN SOCKET s
,
371 IN CONST
struct sockaddr
*name
,
373 IN LPWSABUF lpCallerData
,
374 OUT LPWSABUF lpCalleeData
,
385 DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s
, name
, namelen
);
388 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
390 /* Get the Socket Context */
391 if ((Socket
= WsSockGetSocket(s
)))
393 /* Get the old open type and set new one */
394 OpenType
= Thread
->OpenType
;
395 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
398 Status
= Socket
->Provider
->Service
.lpWSPJoinLeaf(s
,
407 /* Restore open type */
408 Thread
->OpenType
= OpenType
;
410 /* Deference the Socket Context */
411 WsSockDereference(Socket
);
413 /* Check if we got a valid socket */
414 if (Status
!= INVALID_SOCKET
)
416 /* Check if we got a new socket */
419 /* Add a new reference */
420 WsSockAddApiReference(Status
);
429 /* No Socket Context Found */
430 ErrorCode
= WSAENOTSOCK
;
434 /* Return with an Error */
435 SetLastError(ErrorCode
);
436 return INVALID_SOCKET
;
444 WSASocketA(IN INT af
,
447 IN LPWSAPROTOCOL_INFOA lpProtocolInfo
,
451 WSAPROTOCOL_INFOW ProtocolInfoW
;
452 LPWSAPROTOCOL_INFOW p
= &ProtocolInfoW
;
454 /* Convert Protocol Info to Wide */
458 memcpy(&ProtocolInfoW
,
460 sizeof(WSAPROTOCOL_INFOA
) - sizeof(CHAR
) * (WSAPROTOCOL_LEN
+ 1));
462 /* Convert the String */
463 MultiByteToWideChar(CP_ACP
,
465 lpProtocolInfo
->szProtocol
,
467 ProtocolInfoW
.szProtocol
,
468 sizeof(ProtocolInfoW
.szProtocol
) / sizeof(WCHAR
));
472 /* No Protocol Info Specified */
476 /* Call the Unicode Function */
477 return WSASocketW(af
,
490 WSASocketW(IN INT af
,
493 IN LPWSAPROTOCOL_INFOW lpProtocolInfo
,
502 PTCATALOG_ENTRY CatalogEntry
;
503 LPWSAPROTOCOL_INFOW ProtocolInfo
;
505 SOCKET Status
= INVALID_SOCKET
;
506 DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af
, type
, protocol
, lpProtocolInfo
);
509 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
512 SetLastError(ErrorCode
);
513 return INVALID_SOCKET
;
516 /* Get the catalog */
517 Catalog
= WsProcGetTCatalog(Process
);
519 /* Find a Provider for the Catalog ID */
522 /* Get the catalog ID */
523 CatalogId
= lpProtocolInfo
->dwCatalogEntryId
;
525 /* Get the Catalog Entry */
526 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
536 /* Get the Catalog Data from the Socket Info */
537 ErrorCode
= WsTcGetEntryFromTriplet(Catalog
,
545 /* Check for Success */
546 if (ErrorCode
== ERROR_SUCCESS
)
548 /* Use the default Protocol Info if none given */
549 ProtocolInfo
= lpProtocolInfo
? lpProtocolInfo
: &CatalogEntry
->ProtocolInfo
;
551 /* Save the open type and set new one */
552 OpenType
= Thread
->OpenType
;
553 Thread
->OpenType
= (dwFlags
& WSA_FLAG_OVERLAPPED
) ?
554 0 : SO_SYNCHRONOUS_NONALERT
;
556 /* Call the Provider to create the Socket */
557 Status
= CatalogEntry
->Provider
->Service
.lpWSPSocket(af
,
564 /* Restore open type */
565 Thread
->OpenType
= OpenType
;
567 /* Get the catalog ID now, and dereference */
568 CatalogId
= ProtocolInfo
->dwCatalogEntryId
;
569 WsTcEntryDereference(CatalogEntry
);
571 /* Did we fail with WSAEINPROGRESS and had no specific provider? */
572 if ((Status
== INVALID_SOCKET
) &&
573 (ErrorCode
== WSAEINPROGRESS
) &&
576 /* In that case, restart the lookup from this ID */
580 /* Check if we got a valid socket */
581 if (Status
!= INVALID_SOCKET
)
583 /* Add an API reference and return */
584 WsSockAddApiReference(Status
);
589 /* Return with an Error */
590 SetLastError(ErrorCode
);
591 return INVALID_SOCKET
;