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
)))
52 Status
= Socket
->Provider
->Service
.lpWSPBind(s
,
56 /* Deference the Socket Context */
57 WsSockDereference(Socket
);
59 /* Return Provider Value */
60 if (Status
== ERROR_SUCCESS
) return Status
;
62 /* If everything seemed fine, then the WSP call failed itself */
63 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
67 /* No Socket Context Found */
68 ErrorCode
= WSAENOTSOCK
;
72 /* Return with an Error */
73 SetLastError(ErrorCode
);
82 closesocket(IN SOCKET s
)
87 DPRINT("closesocket: %lx\n", s
);
89 /* Check for WSAStartup */
90 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
92 /* Get the Socket Context */
93 if ((Socket
= WsSockGetSocket(s
)))
96 Status
= Socket
->Provider
->Service
.lpWSPCloseSocket(s
, &ErrorCode
);
98 /* Check if this is a provider socket */
99 if ((Status
== ERROR_SUCCESS
) && (Socket
->IsProvider
))
101 /* Disassociate the handle */
102 if (WsSockDisassociateHandle(Socket
) == ERROR_SUCCESS
)
104 /* Deference the Socket Context */
105 WsSockDereference(Socket
);
108 /* Remove the last reference */
109 WsSockDereference(Socket
);
111 /* Return success if everything is OK */
112 if (ErrorCode
== ERROR_SUCCESS
) return ErrorCode
;
117 /* No Socket Context Found */
118 ErrorCode
= WSAENOTSOCK
;
122 /* Return with an Error */
123 SetLastError(ErrorCode
);
140 DPRINT("socket: %lx, %lx, %lx\n", af
, type
, protocol
);
143 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
146 SetLastError(ErrorCode
);
147 return INVALID_SOCKET
;
150 /* Check the current open type and use overlapped if it's default */
151 if (!Thread
->OpenType
) Flags
= WSA_FLAG_OVERLAPPED
;
153 /* Make the protocol negative if this is NETBIOS */
154 if ((af
== AF_NETBIOS
) && (protocol
> 0)) protocol
*= -1;
156 /* Now let WSA handle it */
157 return WSASocketW(af
, type
, protocol
, NULL
, 0, Flags
);
165 WPUCloseSocketHandle(IN SOCKET s
,
177 WPUCreateSocketHandle(IN DWORD dwCatalogEntryId
,
178 IN DWORD_PTR dwContext
,
190 WPUModifyIFSHandle(IN DWORD dwCatalogEntryId
,
191 IN SOCKET ProposedHandle
,
194 SOCKET Handle
= INVALID_SOCKET
;
195 DWORD ErrorCode
= ERROR_SUCCESS
;
198 PTCATALOG_ENTRY Entry
;
200 DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId
, ProposedHandle
);
202 /* Get the current process */
203 if ((Process
= WsGetProcess()))
205 /* Get the Transport Catalog */
206 if ((Catalog
= WsProcGetTCatalog(Process
)))
208 /* Get the entry for this ID */
209 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
212 /* Check for success */
213 if (ErrorCode
== ERROR_SUCCESS
)
215 /* Create a socket object */
216 if ((Socket
= WsSockAllocate()))
219 WsSockInitialize(Socket
, Entry
);
222 ErrorCode
= WsSockAssociateHandle(Socket
,
225 /* Check for success */
226 if (ErrorCode
== ERROR_SUCCESS
)
229 Handle
= ProposedHandle
;
230 *lpErrno
= ERROR_SUCCESS
;
235 WsSockDereference(Socket
);
236 *lpErrno
= ErrorCode
;
239 /* Dereference the extra count */
240 WsSockDereference(Socket
);
244 /* No memory to allocate a socket */
245 *lpErrno
= WSAENOBUFS
;
248 /* Dereference the catalog entry */
249 WsTcEntryDereference(Entry
);
253 /* Entry not found */
254 *lpErrno
= ErrorCode
;
259 /* Catalog not found */
260 *lpErrno
= WSANOTINITIALISED
;
265 /* Process not ready */
266 *lpErrno
= WSANOTINITIALISED
;
278 WPUQuerySocketHandleContext(IN SOCKET s
,
279 OUT PDWORD_PTR lpContext
,
291 WSAAccept(IN SOCKET s
,
293 IN OUT LPINT addrlen
,
294 IN LPCONDITIONPROC lpfnCondition
,
295 IN DWORD_PTR dwCallbackData
)
303 DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s
, addr
, addrlen
, lpfnCondition
);
306 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
308 /* Get the Socket Context */
309 if ((Socket
= WsSockGetSocket(s
)))
311 /* Get the old open type and set new one */
312 OpenType
= Thread
->OpenType
;
313 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
316 Status
= Socket
->Provider
->Service
.lpWSPAccept(s
,
322 /* Restore open type */
323 Thread
->OpenType
= OpenType
;
325 /* Deference the Socket Context */
326 WsSockDereference(Socket
);
328 /* Check if we got a valid socket */
329 if (Status
!= INVALID_SOCKET
)
331 /* Check if we got a new socket */
334 /* Add a new reference */
335 WsSockAddApiReference(Status
);
344 /* No Socket Context Found */
345 ErrorCode
= WSAENOTSOCK
;
349 /* Return with an Error */
350 SetLastError(ErrorCode
);
351 return INVALID_SOCKET
;
359 WSAJoinLeaf(IN SOCKET s
,
360 IN CONST
struct sockaddr
*name
,
362 IN LPWSABUF lpCallerData
,
363 OUT LPWSABUF lpCalleeData
,
374 DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s
, name
, namelen
);
377 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
379 /* Get the Socket Context */
380 if ((Socket
= WsSockGetSocket(s
)))
382 /* Get the old open type and set new one */
383 OpenType
= Thread
->OpenType
;
384 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
387 Status
= Socket
->Provider
->Service
.lpWSPJoinLeaf(s
,
396 /* Restore open type */
397 Thread
->OpenType
= OpenType
;
399 /* Deference the Socket Context */
400 WsSockDereference(Socket
);
402 /* Check if we got a valid socket */
403 if (Status
!= INVALID_SOCKET
)
405 /* Check if we got a new socket */
408 /* Add a new reference */
409 WsSockAddApiReference(Status
);
418 /* No Socket Context Found */
419 ErrorCode
= WSAENOTSOCK
;
423 /* Return with an Error */
424 SetLastError(ErrorCode
);
425 return INVALID_SOCKET
;
433 WSASocketA(IN INT af
,
436 IN LPWSAPROTOCOL_INFOA lpProtocolInfo
,
440 WSAPROTOCOL_INFOW ProtocolInfoW
;
441 LPWSAPROTOCOL_INFOW p
= &ProtocolInfoW
;
443 /* Convert Protocol Info to Wide */
447 memcpy(&ProtocolInfoW
,
449 sizeof(WSAPROTOCOL_INFOA
) - sizeof(CHAR
) * (WSAPROTOCOL_LEN
+ 1));
451 /* Convert the String */
452 MultiByteToWideChar(CP_ACP
,
454 lpProtocolInfo
->szProtocol
,
456 ProtocolInfoW
.szProtocol
,
457 sizeof(ProtocolInfoW
.szProtocol
) / sizeof(WCHAR
));
461 /* No Protocol Info Specified */
465 /* Call the Unicode Function */
466 return WSASocketW(af
,
479 WSASocketW(IN INT af
,
482 IN LPWSAPROTOCOL_INFOW lpProtocolInfo
,
491 PTCATALOG_ENTRY CatalogEntry
;
492 LPWSAPROTOCOL_INFOW ProtocolInfo
;
494 SOCKET Status
= INVALID_SOCKET
;
495 DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af
, type
, protocol
, lpProtocolInfo
);
498 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
501 SetLastError(ErrorCode
);
502 return INVALID_SOCKET
;
505 /* Get the catalog */
506 Catalog
= WsProcGetTCatalog(Process
);
508 /* Find a Provider for the Catalog ID */
511 /* Get the catalog ID */
512 CatalogId
= lpProtocolInfo
->dwCatalogEntryId
;
514 /* Get the Catalog Entry */
515 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
525 /* Get the Catalog Data from the Socket Info */
526 ErrorCode
= WsTcGetEntryFromTriplet(Catalog
,
534 /* Check for Success */
535 if (ErrorCode
== ERROR_SUCCESS
)
537 /* Use the default Protocol Info if none given */
538 ProtocolInfo
= lpProtocolInfo
? lpProtocolInfo
: &CatalogEntry
->ProtocolInfo
;
540 /* Save the open type and set new one */
541 OpenType
= Thread
->OpenType
;
542 Thread
->OpenType
= (dwFlags
& WSA_FLAG_OVERLAPPED
) ?
543 0 : SO_SYNCHRONOUS_NONALERT
;
545 /* Call the Provider to create the Socket */
546 Status
= CatalogEntry
->Provider
->Service
.lpWSPSocket(af
,
553 /* Restore open type */
554 Thread
->OpenType
= OpenType
;
556 /* Get the catalog ID now, and dereference */
557 CatalogId
= ProtocolInfo
->dwCatalogEntryId
;
558 WsTcEntryDereference(CatalogEntry
);
560 /* Did we fail with WSAEINPROGRESS and had no specific provider? */
561 if ((Status
== INVALID_SOCKET
) &&
562 (ErrorCode
== WSAEINPROGRESS
) &&
565 /* In that case, restart the lookup from this ID */
569 /* Check if we got a valid socket */
570 if (Status
!= INVALID_SOCKET
)
572 /* Add an API reference and return */
573 WsSockAddApiReference(Status
);
578 /* Return with an Error */
579 SetLastError(ErrorCode
);
580 return INVALID_SOCKET
;