2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
5 * PURPOSE: Socket Lifetime Support
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES ******************************************************************/
15 /* DATA **********************************************************************/
17 /* FUNCTIONS *****************************************************************/
29 return WSAAccept(s
, addr
, addrlen
, NULL
, 0);
38 IN CONST
struct sockaddr
*name
,
44 DPRINT("bind: %lx, %p, %lx\n", s
, name
, namelen
);
46 /* Check for WSAStartup */
47 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
49 /* Get the Socket Context */
50 if ((Socket
= WsSockGetSocket(s
)))
53 Status
= Socket
->Provider
->Service
.lpWSPBind(s
,
57 /* Deference the Socket Context */
58 WsSockDereference(Socket
);
60 /* Return Provider Value */
61 if (Status
== ERROR_SUCCESS
) return Status
;
63 /* If everything seemed fine, then the WSP call failed itself */
64 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
68 /* No Socket Context Found */
69 ErrorCode
= WSAENOTSOCK
;
73 /* Return with an Error */
74 SetLastError(ErrorCode
);
83 closesocket(IN SOCKET s
)
88 DPRINT("closesocket: %lx\n", s
);
90 /* Check for WSAStartup */
91 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
93 /* Get the Socket Context */
94 if ((Socket
= WsSockGetSocket(s
)))
97 Status
= Socket
->Provider
->Service
.lpWSPCloseSocket(s
, &ErrorCode
);
99 /* Check if this is a provider socket */
100 if ((Status
== ERROR_SUCCESS
) && (Socket
->IsProvider
))
102 /* Disassociate the handle */
103 if (WsSockDisassociateHandle(Socket
) == ERROR_SUCCESS
)
105 /* Deference the Socket Context */
106 WsSockDereference(Socket
);
109 /* Remove the last reference */
110 WsSockDereference(Socket
);
112 /* Return success if everything is OK */
113 if (ErrorCode
== ERROR_SUCCESS
) return ErrorCode
;
118 /* No Socket Context Found */
119 ErrorCode
= WSAENOTSOCK
;
123 /* Return with an Error */
124 SetLastError(ErrorCode
);
141 DPRINT("socket: %lx, %lx, %lx\n", af
, type
, protocol
);
144 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
147 SetLastError(ErrorCode
);
148 return INVALID_SOCKET
;
151 /* Check the current open type and use overlapped if it's default */
152 if (!Thread
->OpenType
) Flags
= WSA_FLAG_OVERLAPPED
;
154 /* Make the protocol negative if this is NETBIOS */
155 if ((af
== AF_NETBIOS
) && (protocol
> 0)) protocol
*= -1;
157 /* Now let WSA handle it */
158 return WSASocketW(af
, type
, protocol
, NULL
, 0, Flags
);
166 WPUCloseSocketHandle(IN SOCKET s
,
178 WPUCreateSocketHandle(IN DWORD dwCatalogEntryId
,
179 IN DWORD_PTR dwContext
,
191 WPUModifyIFSHandle(IN DWORD dwCatalogEntryId
,
192 IN SOCKET ProposedHandle
,
195 SOCKET Handle
= INVALID_SOCKET
;
196 DWORD ErrorCode
= ERROR_SUCCESS
;
199 PTCATALOG_ENTRY Entry
;
201 DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId
, ProposedHandle
);
203 /* Get the current process */
204 if ((Process
= WsGetProcess()))
206 /* Get the Transport Catalog */
207 if ((Catalog
= WsProcGetTCatalog(Process
)))
209 /* Get the entry for this ID */
210 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
213 /* Check for success */
214 if (ErrorCode
== ERROR_SUCCESS
)
216 /* Create a socket object */
217 if ((Socket
= WsSockAllocate()))
220 WsSockInitialize(Socket
, Entry
);
223 ErrorCode
= WsSockAssociateHandle(Socket
,
226 /* Check for success */
227 if (ErrorCode
== ERROR_SUCCESS
)
230 Handle
= ProposedHandle
;
231 *lpErrno
= ERROR_SUCCESS
;
236 WsSockDereference(Socket
);
237 *lpErrno
= ErrorCode
;
240 /* Dereference the extra count */
241 WsSockDereference(Socket
);
245 /* No memory to allocate a socket */
246 *lpErrno
= WSAENOBUFS
;
249 /* Dereference the catalog entry */
250 WsTcEntryDereference(Entry
);
254 /* Entry not found */
255 *lpErrno
= ErrorCode
;
260 /* Catalog not found */
261 *lpErrno
= WSANOTINITIALISED
;
266 /* Process not ready */
267 *lpErrno
= WSANOTINITIALISED
;
279 WPUQuerySocketHandleContext(IN SOCKET s
,
280 OUT PDWORD_PTR lpContext
,
292 WSAAccept(IN SOCKET s
,
294 IN OUT LPINT addrlen
,
295 IN LPCONDITIONPROC lpfnCondition
,
296 IN DWORD_PTR dwCallbackData
)
304 DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s
, addr
, addrlen
, lpfnCondition
);
307 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
309 /* Get the Socket Context */
310 if ((Socket
= WsSockGetSocket(s
)))
312 /* Get the old open type and set new one */
313 OpenType
= Thread
->OpenType
;
314 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
317 Status
= Socket
->Provider
->Service
.lpWSPAccept(s
,
323 /* Restore open type */
324 Thread
->OpenType
= OpenType
;
326 /* Deference the Socket Context */
327 WsSockDereference(Socket
);
329 /* Check if we got a valid socket */
330 if (Status
!= INVALID_SOCKET
)
332 /* Check if we got a new socket */
335 /* Add a new reference */
336 WsSockAddApiReference(Status
);
345 /* No Socket Context Found */
346 ErrorCode
= WSAENOTSOCK
;
350 /* Return with an Error */
351 SetLastError(ErrorCode
);
352 return INVALID_SOCKET
;
360 WSAJoinLeaf(IN SOCKET s
,
361 IN CONST
struct sockaddr
*name
,
363 IN LPWSABUF lpCallerData
,
364 OUT LPWSABUF lpCalleeData
,
375 DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s
, name
, namelen
);
378 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
380 /* Get the Socket Context */
381 if ((Socket
= WsSockGetSocket(s
)))
383 /* Get the old open type and set new one */
384 OpenType
= Thread
->OpenType
;
385 Thread
->OpenType
= Socket
->Overlapped
? 0 : SO_SYNCHRONOUS_NONALERT
;
388 Status
= Socket
->Provider
->Service
.lpWSPJoinLeaf(s
,
397 /* Restore open type */
398 Thread
->OpenType
= OpenType
;
400 /* Deference the Socket Context */
401 WsSockDereference(Socket
);
403 /* Check if we got a valid socket */
404 if (Status
!= INVALID_SOCKET
)
406 /* Check if we got a new socket */
409 /* Add a new reference */
410 WsSockAddApiReference(Status
);
419 /* No Socket Context Found */
420 ErrorCode
= WSAENOTSOCK
;
424 /* Return with an Error */
425 SetLastError(ErrorCode
);
426 return INVALID_SOCKET
;
434 WSASocketA(IN INT af
,
437 IN LPWSAPROTOCOL_INFOA lpProtocolInfo
,
441 WSAPROTOCOL_INFOW ProtocolInfoW
;
442 LPWSAPROTOCOL_INFOW p
= &ProtocolInfoW
;
444 /* Convert Protocol Info to Wide */
448 memcpy(&ProtocolInfoW
,
450 sizeof(WSAPROTOCOL_INFOA
) - sizeof(CHAR
) * (WSAPROTOCOL_LEN
+ 1));
452 /* Convert the String */
453 MultiByteToWideChar(CP_ACP
,
455 lpProtocolInfo
->szProtocol
,
457 ProtocolInfoW
.szProtocol
,
458 sizeof(ProtocolInfoW
.szProtocol
) / sizeof(WCHAR
));
462 /* No Protocol Info Specified */
466 /* Call the Unicode Function */
467 return WSASocketW(af
,
480 WSASocketW(IN INT af
,
483 IN LPWSAPROTOCOL_INFOW lpProtocolInfo
,
492 PTCATALOG_ENTRY CatalogEntry
;
493 LPWSAPROTOCOL_INFOW ProtocolInfo
;
495 SOCKET Status
= INVALID_SOCKET
;
496 DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af
, type
, protocol
, lpProtocolInfo
);
499 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) != ERROR_SUCCESS
)
502 SetLastError(ErrorCode
);
503 return INVALID_SOCKET
;
506 /* Get the catalog */
507 Catalog
= WsProcGetTCatalog(Process
);
509 /* Find a Provider for the Catalog ID */
512 /* Get the catalog ID */
513 CatalogId
= lpProtocolInfo
->dwCatalogEntryId
;
515 /* Get the Catalog Entry */
516 ErrorCode
= WsTcGetEntryFromCatalogEntryId(Catalog
,
526 /* Get the Catalog Data from the Socket Info */
527 ErrorCode
= WsTcGetEntryFromTriplet(Catalog
,
535 /* Check for Success */
536 if (ErrorCode
== ERROR_SUCCESS
)
538 /* Use the default Protocol Info if none given */
539 ProtocolInfo
= lpProtocolInfo
? lpProtocolInfo
: &CatalogEntry
->ProtocolInfo
;
541 /* Save the open type and set new one */
542 OpenType
= Thread
->OpenType
;
543 Thread
->OpenType
= (dwFlags
& WSA_FLAG_OVERLAPPED
) ?
544 0 : SO_SYNCHRONOUS_NONALERT
;
546 /* Call the Provider to create the Socket */
547 Status
= CatalogEntry
->Provider
->Service
.lpWSPSocket(af
,
554 /* Restore open type */
555 Thread
->OpenType
= OpenType
;
557 /* Get the catalog ID now, and dereference */
558 CatalogId
= ProtocolInfo
->dwCatalogEntryId
;
559 WsTcEntryDereference(CatalogEntry
);
561 /* Did we fail with WSAEINPROGRESS and had no specific provider? */
562 if ((Status
== INVALID_SOCKET
) &&
563 (ErrorCode
== WSAEINPROGRESS
) &&
566 /* In that case, restart the lookup from this ID */
570 /* Check if we got a valid socket */
571 if (Status
!= INVALID_SOCKET
)
573 /* Add an API reference and return */
574 WsSockAddApiReference(Status
);
579 /* Return with an Error */
580 SetLastError(ErrorCode
);
581 return INVALID_SOCKET
;