ReactOS 0.4.15-dev-7659-ga55345b
socklife.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32/src/socklife.c
5 * PURPOSE: Socket Lifetime Support
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ws2_32.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS *****************************************************************/
17
18/*
19 * @implemented
20 */
25 OUT INT FAR* addrlen)
26{
27 /* Let WSA do it */
28 return WSAAccept(s, addr, addrlen, NULL, 0);
29}
30
31/*
32 * @implemented
33 */
34INT
37 IN CONST struct sockaddr *name,
39{
40 PWSSOCKET Socket;
41 INT Status;
43 DPRINT("bind: %lx, %p, %lx\n", s, name, namelen);
44
45 /* Check for WSAStartup */
47 {
48 /* Get the Socket Context */
49 if ((Socket = WsSockGetSocket(s)))
50 {
51 if (name && (namelen >= sizeof(*name)))
52 {
53 /* Make the call */
55 name,
56 namelen,
57 &ErrorCode);
58 /* Deference the Socket Context */
59 WsSockDereference(Socket);
60
61 /* Return Provider Value */
62 if (Status == ERROR_SUCCESS) return Status;
63
64 /* If everything seemed fine, then the WSP call failed itself */
66 }
67 else
68 {
69 /* Deference the Socket Context */
70 WsSockDereference(Socket);
71
72 /* name or namelen not valid */
74 }
75 }
76 else
77 {
78 /* No Socket Context Found */
80 }
81 }
82
83 /* Return with an Error */
85 return SOCKET_ERROR;
86}
87
88/*
89 * @implemented
90 */
91INT
94{
95 PWSSOCKET Socket;
96 INT Status;
98 DPRINT("closesocket: %lx\n", s);
99
100 /* Check for WSAStartup */
102 {
103 /* Get the Socket Context */
104 if ((Socket = WsSockGetSocket(s)))
105 {
106 /* Make the call */
108
109 /* Check if this is a provider socket */
110 if ((Status == ERROR_SUCCESS) && (Socket->IsProvider))
111 {
112 /* Disassociate the handle */
114 {
115 /* Deference the Socket Context */
116 WsSockDereference(Socket);
117 }
118
119 /* Remove the last reference */
120 WsSockDereference(Socket);
121
122 /* Return success if everything is OK */
123 if (ErrorCode == ERROR_SUCCESS) return ErrorCode;
124 }
125 }
126 else
127 {
128 /* No Socket Context Found */
130 }
131 }
132
133 /* Return with an Error */
135 return SOCKET_ERROR;
136}
137
138/*
139 * @implemented
140 */
141SOCKET
142WSAAPI
144 IN INT type,
146{
149 DWORD Flags = 0;
151 DPRINT("socket: %lx, %lx, %lx\n", af, type, protocol);
152
153 /* Enter prolog */
155 {
156 /* Fail here */
158 return INVALID_SOCKET;
159 }
160
161 /* Check the current open type and use overlapped if it's default */
162 if (!Thread->OpenType) Flags = WSA_FLAG_OVERLAPPED;
163
164 /* Make the protocol negative if this is NETBIOS */
165 if ((af == AF_NETBIOS) && (protocol > 0)) protocol *= -1;
166
167 /* Now let WSA handle it */
168 return WSASocketW(af, type, protocol, NULL, 0, Flags);
169}
170
171/*
172 * @unimplemented
173 */
174INT
175WSPAPI
177 OUT LPINT lpErrno)
178{
180 return 0;
181}
182
183/*
184 * @unimplemented
185 */
186SOCKET
187WSPAPI
189 IN DWORD_PTR dwContext,
190 OUT LPINT lpErrno)
191{
193 return (SOCKET)0;
194}
195
196/*
197 * @implemented
198 */
199SOCKET
200WSPAPI
201WPUModifyIFSHandle(IN DWORD dwCatalogEntryId,
202 IN SOCKET ProposedHandle,
203 OUT LPINT lpErrno)
204{
208 PTCATALOG Catalog;
210 PWSSOCKET Socket;
211 DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId, ProposedHandle);
212
213 /* Get the current process */
214 if ((Process = WsGetProcess()))
215 {
216 /* Get the Transport Catalog */
217 if ((Catalog = WsProcGetTCatalog(Process)))
218 {
219 /* Get the entry for this ID */
221 dwCatalogEntryId,
222 &Entry);
223 /* Check for success */
225 {
226 /* Create a socket object */
227 if ((Socket = WsSockAllocate()))
228 {
229 /* Initialize it */
230 WsSockInitialize(Socket, Entry);
231
232 /* Associate it */
234 ProposedHandle,
235 TRUE);
236 /* Check for success */
238 {
239 /* Return */
240 Handle = ProposedHandle;
241 *lpErrno = ERROR_SUCCESS;
242 }
243 else
244 {
245 /* Fail */
246 WsSockDereference(Socket);
247 *lpErrno = ErrorCode;
248 }
249
250 /* Dereference the extra count */
251 WsSockDereference(Socket);
252 }
253 else
254 {
255 /* No memory to allocate a socket */
256 *lpErrno = WSAENOBUFS;
257 }
258
259 /* Dereference the catalog entry */
261 }
262 else
263 {
264 /* Entry not found */
265 *lpErrno = ErrorCode;
266 }
267 }
268 else
269 {
270 /* Catalog not found */
271 *lpErrno = WSANOTINITIALISED;
272 }
273 }
274 else
275 {
276 /* Process not ready */
277 *lpErrno = WSANOTINITIALISED;
278 }
279
280 /* Return */
281 return Handle;
282}
283
284/*
285 * @unimplemented
286 */
287INT
288WSPAPI
290 OUT PDWORD_PTR lpContext,
291 OUT LPINT lpErrno)
292{
294 return 0;
295}
296
297/*
298 * @implemented
299 */
300SOCKET
301WSAAPI
304 IN OUT LPINT addrlen,
305 IN LPCONDITIONPROC lpfnCondition,
306 IN DWORD_PTR dwCallbackData)
307{
310 PWSSOCKET Socket;
311 DWORD OpenType;
314 DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s, addr, addrlen, lpfnCondition);
315
316 /* Enter prolog */
318 {
319 /* Get the Socket Context */
320 if ((Socket = WsSockGetSocket(s)))
321 {
322 /* Get the old open type and set new one */
323 OpenType = Thread->OpenType;
324 Thread->OpenType = Socket->Overlapped ? 0 : SO_SYNCHRONOUS_NONALERT;
325
326 /* Make the call */
328 addr,
329 addrlen,
330 lpfnCondition,
331 dwCallbackData,
332 &ErrorCode);
333 /* Restore open type */
334 Thread->OpenType = OpenType;
335
336 /* Deference the Socket Context */
337 WsSockDereference(Socket);
338
339 /* Check if we got a valid socket */
340 if (Status != INVALID_SOCKET)
341 {
342 /* Check if we got a new socket */
343 if (Status != s)
344 {
345 /* Add a new reference */
347 }
348
349 /* Return */
350 return Status;
351 }
352 }
353 else
354 {
355 /* No Socket Context Found */
357 }
358 }
359
360 /* Return with an Error */
362 return INVALID_SOCKET;
363}
364
365/*
366 * @implemented
367 */
368SOCKET
369WSAAPI
371 IN CONST struct sockaddr *name,
372 IN INT namelen,
373 IN LPWSABUF lpCallerData,
374 OUT LPWSABUF lpCalleeData,
375 IN LPQOS lpSQOS,
376 IN LPQOS lpGQOS,
378{
381 PWSSOCKET Socket;
382 DWORD OpenType;
385 DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s, name, namelen);
386
387 /* Enter prolog */
389 {
390 /* Get the Socket Context */
391 if ((Socket = WsSockGetSocket(s)))
392 {
393 /* Get the old open type and set new one */
394 OpenType = Thread->OpenType;
395 Thread->OpenType = Socket->Overlapped ? 0 : SO_SYNCHRONOUS_NONALERT;
396
397 /* Make the call */
399 name,
400 namelen,
401 lpCallerData,
402 lpCalleeData,
403 lpSQOS,
404 lpGQOS,
405 dwFlags,
406 &ErrorCode);
407 /* Restore open type */
408 Thread->OpenType = OpenType;
409
410 /* Deference the Socket Context */
411 WsSockDereference(Socket);
412
413 /* Check if we got a valid socket */
414 if (Status != INVALID_SOCKET)
415 {
416 /* Check if we got a new socket */
417 if (Status != s)
418 {
419 /* Add a new reference */
421 }
422
423 /* Return */
424 return Status;
425 }
426 }
427 else
428 {
429 /* No Socket Context Found */
431 }
432 }
433
434 /* Return with an Error */
436 return INVALID_SOCKET;
437}
438
439/*
440 * @implemented
441 */
442SOCKET
443WSAAPI
445 IN INT type,
447 IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
448 IN GROUP g,
450{
451 WSAPROTOCOL_INFOW ProtocolInfoW;
452 LPWSAPROTOCOL_INFOW p = &ProtocolInfoW;
453
454 /* Convert Protocol Info to Wide */
455 if (lpProtocolInfo)
456 {
457 /* Copy the Data */
458 memcpy(&ProtocolInfoW,
459 lpProtocolInfo,
460 sizeof(WSAPROTOCOL_INFOA) - sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));
461
462 /* Convert the String */
464 0,
465 lpProtocolInfo->szProtocol,
466 -1,
467 ProtocolInfoW.szProtocol,
468 sizeof(ProtocolInfoW.szProtocol) / sizeof(WCHAR));
469 }
470 else
471 {
472 /* No Protocol Info Specified */
473 p = NULL;
474 }
475
476 /* Call the Unicode Function */
477 return WSASocketW(af,
478 type,
479 protocol,
480 p,
481 g,
482 dwFlags);
483}
484
485/*
486 * @implemented
487 */
488SOCKET
489WSAAPI
491 IN INT type,
493 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
494 IN GROUP g,
496{
500 PTCATALOG Catalog;
501 DWORD CatalogId;
502 PTCATALOG_ENTRY CatalogEntry;
503 LPWSAPROTOCOL_INFOW ProtocolInfo;
504 DWORD OpenType;
506 DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af, type, protocol, lpProtocolInfo);
507
508 /* Enter prolog */
510 {
511 /* Fail now */
513 return INVALID_SOCKET;
514 }
515
516 /* Get the catalog */
517 Catalog = WsProcGetTCatalog(Process);
518
519 /* Find a Provider for the Catalog ID */
520 if (lpProtocolInfo)
521 {
522 /* Get the catalog ID */
523 CatalogId = lpProtocolInfo->dwCatalogEntryId;
524
525 /* Get the Catalog Entry */
527 CatalogId,
528 &CatalogEntry);
529 }
530 else
531 {
532 /* No ID */
533 CatalogId = 0;
534
535DoLookup:
536 /* Get the Catalog Data from the Socket Info */
538 af,
539 type,
540 protocol,
541 CatalogId,
542 &CatalogEntry);
543 }
544
545 /* Check for Success */
547 {
548 /* Use the default Protocol Info if none given */
549 ProtocolInfo = lpProtocolInfo ? lpProtocolInfo : &CatalogEntry->ProtocolInfo;
550
551 /* Save the open type and set new one */
552 OpenType = Thread->OpenType;
553 Thread->OpenType = (dwFlags & WSA_FLAG_OVERLAPPED) ?
555
556 /* Call the Provider to create the Socket */
557 Status = CatalogEntry->Provider->Service.lpWSPSocket(af,
558 type,
559 protocol,
560 ProtocolInfo,
561 g,
562 dwFlags,
563 &ErrorCode);
564 /* Restore open type */
565 Thread->OpenType = OpenType;
566
567 /* Get the catalog ID now, and dereference */
568 CatalogId = ProtocolInfo->dwCatalogEntryId;
569 WsTcEntryDereference(CatalogEntry);
570
571 /* Did we fail with WSAEINPROGRESS and had no specific provider? */
572 if ((Status == INVALID_SOCKET) &&
574 !(lpProtocolInfo))
575 {
576 /* In that case, restart the lookup from this ID */
577 goto DoLookup;
578 }
579
580 /* Check if we got a valid socket */
581 if (Status != INVALID_SOCKET)
582 {
583 /* Add an API reference and return */
585 return Status;
586 }
587 }
588
589 /* Return with an Error */
591 return INVALID_SOCKET;
592}
ULONG_PTR * PDWORD_PTR
Definition: basetsd.h:182
#define UNIMPLEMENTED
Definition: debug.h:115
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define MultiByteToWideChar
Definition: compat.h:110
#define FAR
Definition: zlib.h:34
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint namelen
Definition: glext.h:7232
GLenum const GLvoid * addr
Definition: glext.h:9621
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define closesocket
Definition: ncftp.h:477
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define CONST
Definition: pedump.c:81
#define DPRINT
Definition: sndvol32.h:71
INT WSPAPI WPUCloseSocketHandle(IN SOCKET s, OUT LPINT lpErrno)
Definition: socklife.c:176
SOCKET WSAAPI WSAJoinLeaf(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen, IN LPWSABUF lpCallerData, OUT LPWSABUF lpCalleeData, IN LPQOS lpSQOS, IN LPQOS lpGQOS, IN DWORD dwFlags)
Definition: socklife.c:370
SOCKET WSAAPI WSASocketA(IN INT af, IN INT type, IN INT protocol, IN LPWSAPROTOCOL_INFOA lpProtocolInfo, IN GROUP g, IN DWORD dwFlags)
Definition: socklife.c:444
SOCKET WSPAPI WPUCreateSocketHandle(IN DWORD dwCatalogEntryId, IN DWORD_PTR dwContext, OUT LPINT lpErrno)
Definition: socklife.c:188
SOCKET WSAAPI WSASocketW(IN INT af, IN INT type, IN INT protocol, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, IN GROUP g, IN DWORD dwFlags)
Definition: socklife.c:490
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI WSAAccept(IN SOCKET s, OUT LPSOCKADDR addr, IN OUT LPINT addrlen, IN LPCONDITIONPROC lpfnCondition, IN DWORD_PTR dwCallbackData)
Definition: socklife.c:302
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
SOCKET WSPAPI WPUModifyIFSHandle(IN DWORD dwCatalogEntryId, IN SOCKET ProposedHandle, OUT LPINT lpErrno)
Definition: socklife.c:201
INT WSPAPI WPUQuerySocketHandleContext(IN SOCKET s, OUT PDWORD_PTR lpContext, OUT LPINT lpErrno)
Definition: socklife.c:289
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
base of all file and directory entries
Definition: entries.h:83
Definition: ws2_32p.h:86
PTPROVIDER Provider
Definition: ws2_32p.h:89
WSAPROTOCOL_INFOW ProtocolInfo
Definition: ws2_32p.h:91
WSPPROC_TABLE Service
Definition: ws2_32p.h:80
WCHAR szProtocol[WSAPROTOCOL_LEN+1]
Definition: winsock2.h:699
DWORD dwCatalogEntryId
Definition: winsock2.h:686
LPWSPCLOSESOCKET lpWSPCloseSocket
Definition: ws2spi.h:467
LPWSPJOINLEAF lpWSPJoinLeaf
Definition: ws2spi.h:478
LPWSPSOCKET lpWSPSocket
Definition: ws2spi.h:489
LPWSPACCEPT lpWSPAccept
Definition: ws2spi.h:461
LPWSPBIND lpWSPBind
Definition: ws2spi.h:464
PTPROVIDER Provider
Definition: ws2_32p.h:199
BOOLEAN IsProvider
Definition: ws2_32p.h:203
BOOLEAN Overlapped
Definition: ws2_32p.h:201
Definition: name.c:39
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
int * LPINT
Definition: windef.h:178
#define WSANOTINITIALISED
Definition: winerror.h:1987
#define WSASYSCALLFAILURE
Definition: winerror.h:1994
#define WSAENOTSOCK
Definition: winerror.h:1951
#define WSAENOBUFS
Definition: winerror.h:1968
#define WSAEINPROGRESS
Definition: winerror.h:1949
#define WSAEFAULT
Definition: winerror.h:1945
unsigned int GROUP
Definition: winsock2.h:640
#define WSAPROTOCOL_LEN
Definition: winsock2.h:428
#define WSA_FLAG_OVERLAPPED
Definition: winsock2.h:466
#define WSAAPI
Definition: winsock2.h:605
int(CALLBACK * LPCONDITIONPROC)(IN LPWSABUF lpCallerId, IN LPWSABUF lpCallerData, IN OUT LPQOS lpSQOS, IN OUT LPQOS lpGQOS, IN LPWSABUF lpCalleeId, IN LPWSABUF lpCalleeData, OUT GROUP FAR *g, IN DWORD_PTR dwCallbackData)
Definition: winsock2.h:711
#define INVALID_SOCKET
Definition: winsock.h:332
#define AF_NETBIOS
Definition: winsock.h:363
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
FORCEINLINE DWORD WsQuickProlog(VOID)
Definition: ws2_32p.h:892
INT WSAAPI WsSockAssociateHandle(IN PWSSOCKET Socket, IN SOCKET Handle, IN BOOLEAN IsProvider)
Definition: dsocket.c:225
INT WSAAPI WsSockInitialize(IN PWSSOCKET Socket, IN PTCATALOG_ENTRY CatalogEntry)
Definition: dsocket.c:67
VOID WSAAPI WsSockDereference(IN PWSSOCKET Socket)
Definition: dsocket.c:205
VOID WSAAPI WsTcEntryDereference(IN PTCATALOG_ENTRY CatalogEntry)
Definition: dcatitem.c:51
DWORD WSAAPI WsTcGetEntryFromCatalogEntryId(IN PTCATALOG TCatalog, IN DWORD CatalogEntryId, IN PTCATALOG_ENTRY *CatalogEntry)
Definition: dcatalog.c:455
FORCEINLINE PWSPROCESS WsGetProcess(VOID)
Definition: ws2_32p.h:885
PWSSOCKET WSAAPI WsSockAllocate(VOID)
Definition: dsocket.c:48
DWORD WSAAPI WsTcGetEntryFromTriplet(IN PTCATALOG TCatalog, IN INT AddressFamily, IN INT SocketType, IN INT Protocol, IN DWORD StartId, IN PTCATALOG_ENTRY *CatalogEntry)
Definition: dcatalog.c:501
PTCATALOG WSAAPI WsProcGetTCatalog(IN PWSPROCESS Process)
Definition: dprocess.c:150
INT WSAAPI WsApiProlog(OUT PWSPROCESS *Process, OUT PWSTHREAD *Thread)
Definition: wsautil.c:91
INT WSAAPI WsSockAddApiReference(IN SOCKET Handle)
Definition: dsocket.c:159
PWSSOCKET WSAAPI WsSockGetSocket(IN SOCKET Handle)
Definition: dsocket.c:140
INT WSAAPI WsSockDisassociateHandle(IN PWSSOCKET Socket)
Definition: dsocket.c:217
#define WSPAPI
Definition: ws2spi.h:39
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175