ReactOS 0.4.16-dev-2284-g3529151
dllmain.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver DLL
4 * FILE: dll/win32/msafd/misc/dllmain.c
5 * PURPOSE: DLL entry point
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Alex Ionescu (alex@relsoft.net)
8 * Pierre Schweitzer (pierre@reactos.org)
9 * REVISIONS:
10 * CSH 01/09-2000 Created
11 * Alex 16/07/2004 - Complete Rewrite
12 */
13
14#include <msafd.h>
15
16#include <winuser.h>
17#include <wchar.h>
18
21DWORD CatalogEntryId; /* CatalogEntryId for upcalls */
30
31
32
33/*
34 * FUNCTION: Creates a new socket
35 * ARGUMENTS:
36 * af = Address family
37 * type = Socket type
38 * protocol = Protocol type
39 * lpProtocolInfo = Pointer to protocol information
40 * g = Reserved
41 * dwFlags = Socket flags
42 * lpErrno = Address of buffer for error information
43 * RETURNS:
44 * Created socket, or INVALID_SOCKET if it could not be created
45 */
49 int SocketType,
50 int Protocol,
51 LPWSAPROTOCOL_INFOW lpProtocolInfo,
52 GROUP g,
54 LPINT lpErrno)
55{
57 IO_STATUS_BLOCK IOSB;
58 USHORT SizeOfPacket;
59 ULONG SizeOfEA;
60 PAFD_CREATE_PACKET AfdPacket;
61 HANDLE Sock;
64 PHELPER_DATA HelperData;
65 PVOID HelperDLLContext;
66 DWORD HelperEvents;
67 UNICODE_STRING TransportName;
68 UNICODE_STRING DevName;
70 INT Status;
71 PSOCK_SHARED_INFO SharedData = NULL;
72
73 TRACE("Creating Socket, getting TDI Name - AddressFamily (%d) SocketType (%d) Protocol (%d).\n",
75
76 if (lpProtocolInfo && lpProtocolInfo->dwServiceFlags3 != 0 && lpProtocolInfo->dwServiceFlags4 != 0)
77 {
78 /* Duplpicating socket from different process */
79 if (UlongToPtr(lpProtocolInfo->dwServiceFlags3) == INVALID_HANDLE_VALUE)
80 {
82 goto error;
83 }
84 if (UlongToPtr(lpProtocolInfo->dwServiceFlags4) == INVALID_HANDLE_VALUE)
85 {
87 goto error;
88 }
89 SharedData = MapViewOfFile(UlongToPtr(lpProtocolInfo->dwServiceFlags3),
91 0,
92 0,
93 sizeof(SOCK_SHARED_INFO));
94 if (!SharedData)
95 {
97 goto error;
98 }
99 InterlockedIncrement(&SharedData->RefCount);
100 AddressFamily = SharedData->AddressFamily;
101 SocketType = SharedData->SocketType;
102 Protocol = SharedData->Protocol;
103 }
104
105 if (AddressFamily == AF_UNSPEC && SocketType == 0 && Protocol == 0)
106 {
108 goto error;
109 }
110
111 /* Set the defaults */
114
115 if (SocketType == 0)
116 {
117 switch (Protocol)
118 {
119 case IPPROTO_TCP:
121 break;
122 case IPPROTO_UDP:
124 break;
125 case IPPROTO_RAW:
127 break;
128 default:
129 TRACE("Unknown Protocol (%d). We will try SOCK_STREAM.\n", Protocol);
131 break;
132 }
133 }
134
135 if (Protocol == 0)
136 {
137 switch (SocketType)
138 {
139 case SOCK_STREAM:
141 break;
142 case SOCK_DGRAM:
144 break;
145 case SOCK_RAW:
147 break;
148 default:
149 TRACE("Unknown SocketType (%d). We will try IPPROTO_TCP.\n", SocketType);
151 break;
152 }
153 }
154
155 /* Get Helper Data and Transport */
157 &SocketType,
158 &Protocol,
159 g,
160 dwFlags,
161 &TransportName,
162 &HelperDLLContext,
163 &HelperData,
164 &HelperEvents);
165
166 /* Check for error */
167 if (Status != NO_ERROR)
168 {
169 ERR("SockGetTdiName: Status %x\n", Status);
170 goto error;
171 }
172
173 /* AFD Device Name */
174 RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint");
175
176 /* Set Socket Data */
177 Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket));
178 if (!Socket)
179 {
181 goto error;
182 }
183 RtlZeroMemory(Socket, sizeof(*Socket));
184 if (SharedData)
185 {
186 Socket->SharedData = SharedData;
187 Socket->SharedDataHandle = UlongToHandle(lpProtocolInfo->dwServiceFlags3);
188 Sock = UlongToHandle(lpProtocolInfo->dwServiceFlags4);
189 Socket->Handle = (SOCKET)lpProtocolInfo->dwServiceFlags4;
190 }
191 else
192 {
194 Socket->SharedData = HeapAlloc(GlobalHeap, 0, sizeof(*Socket->SharedData));
195 if (!Socket->SharedData)
196 {
198 goto error;
199 }
200 RtlZeroMemory(Socket->SharedData, sizeof(*Socket->SharedData));
201 Socket->SharedData->State = SocketOpen;
202 Socket->SharedData->RefCount = 1L;
203 Socket->SharedData->Listening = FALSE;
206 Socket->SharedData->Protocol = Protocol;
207 Socket->SharedData->SizeOfLocalAddress = HelperData->MaxWSAddressLength;
210 Socket->SharedData->CreateFlags = dwFlags;
211 Socket->SharedData->ServiceFlags1 = lpProtocolInfo->dwServiceFlags1;
212 Socket->SharedData->ProviderFlags = lpProtocolInfo->dwProviderFlags;
213 Socket->SharedData->UseSAN = FALSE;
214 Socket->SharedData->NonBlocking = FALSE; /* Sockets start blocking */
217 Socket->SharedData->OobInline = FALSE;
218
219 /* Ask alex about this */
220 if( Socket->SharedData->SocketType == SOCK_DGRAM ||
221 Socket->SharedData->SocketType == SOCK_RAW )
222 {
223 TRACE("Connectionless socket\n");
225 }
226 Socket->Handle = INVALID_SOCKET;
227 }
228
229 Socket->HelperContext = HelperDLLContext;
230 Socket->HelperData = HelperData;
231 Socket->HelperEvents = HelperEvents;
232 Socket->LocalAddress = &Socket->SharedData->WSLocalAddress;
233 Socket->RemoteAddress = &Socket->SharedData->WSRemoteAddress;
234 Socket->SanData = NULL;
235 RtlCopyMemory(&Socket->ProtocolInfo, lpProtocolInfo, sizeof(Socket->ProtocolInfo));
236 if (SharedData)
237 goto ok;
238
239 /* Packet Size */
240 SizeOfPacket = TransportName.Length + sizeof(AFD_CREATE_PACKET) + sizeof(WCHAR);
241
242 /* EA Size */
243 SizeOfEA = SizeOfPacket + sizeof(FILE_FULL_EA_INFORMATION) + AFD_PACKET_COMMAND_LENGTH;
244
245 /* Set up EA Buffer */
246 EABuffer = HeapAlloc(GlobalHeap, 0, SizeOfEA);
247 if (!EABuffer)
248 {
250 goto error;
251 }
252
253 RtlZeroMemory(EABuffer, SizeOfEA);
254 EABuffer->NextEntryOffset = 0;
255 EABuffer->Flags = 0;
257 RtlCopyMemory (EABuffer->EaName,
260 EABuffer->EaValueLength = SizeOfPacket;
261
262 /* Set up AFD Packet */
263 AfdPacket = (PAFD_CREATE_PACKET)(EABuffer->EaName + EABuffer->EaNameLength + 1);
264 AfdPacket->SizeOfTransportName = TransportName.Length;
265 RtlCopyMemory (AfdPacket->TransportName,
266 TransportName.Buffer,
267 TransportName.Length + sizeof(WCHAR));
268 AfdPacket->GroupID = g;
269
270 /* Set up Endpoint Flags */
271 if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS) != 0)
272 {
273 if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW))
274 {
275 /* Only RAW or UDP can be Connectionless */
277 goto error;
278 }
280 }
281
282 if ((Socket->SharedData->ServiceFlags1 & XP1_MESSAGE_ORIENTED) != 0)
283 {
284 if (SocketType == SOCK_STREAM)
285 {
286 if ((Socket->SharedData->ServiceFlags1 & XP1_PSEUDO_STREAM) == 0)
287 {
288 /* The Provider doesn't actually support Message Oriented Streams */
290 goto error;
291 }
292 }
294 }
295
297
302 {
303 if ((Socket->SharedData->ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0)
304 {
305 /* The Provider doesn't actually support Multipoint */
307 goto error;
308 }
310
312 {
315 {
316 /* The Provider doesn't support Control Planes, or you already gave a leaf */
318 goto error;
319 }
321 }
322
324 {
327 {
328 /* The Provider doesn't support Data Planes, or you already gave a leaf */
330 goto error;
331 }
333 }
334 }
335
336 /* Set up Object Attributes */
338 &DevName,
340 0,
341 0);
342
343 /* Create the Socket as asynchronous. That means we have to block
344 ourselves after every call to NtDeviceIoControlFile. This is
345 because the kernel doesn't support overlapping synchronous I/O
346 requests (made from multiple threads) at this time (Sep 2005) */
347 Status = NtCreateFile(&Sock,
349 &Object,
350 &IOSB,
351 NULL,
352 0,
355 0,
356 EABuffer,
357 SizeOfEA);
358
359 HeapFree(GlobalHeap, 0, EABuffer);
360
361 if (!NT_SUCCESS(Status))
362 {
363 ERR("Failed to open socket. Status 0x%08x\n", Status);
365 goto error;
366 }
367
368 /* Save Handle */
369 Socket->Handle = (SOCKET)Sock;
370
371 /* Save Group Info */
372 if (g != 0)
373 {
376 NULL,
377 NULL,
378 &GroupData,
379 NULL,
380 NULL);
381 Socket->SharedData->GroupID = GroupData.u.LowPart;
382 Socket->SharedData->GroupType = GroupData.u.HighPart;
383 }
384
385 /* Get Window Sizes and Save them */
386 GetSocketInformation (Socket,
388 NULL,
390 NULL,
391 NULL,
392 NULL);
393
394 GetSocketInformation (Socket,
396 NULL,
398 NULL,
399 NULL,
400 NULL);
401ok:
402
403 /* Save in Process Sockets List */
405 Socket->NextSocket = SocketListHead;
406 SocketListHead = Socket;
408
409 /* Create the Socket Context */
410 CreateContext(Socket);
411
412 /* Notify Winsock */
414
415 /* Return Socket Handle */
416 TRACE("Success %x\n", Sock);
417
418 return (SOCKET)Sock;
419
420error:
421 TRACE("Ending %x\n", Status);
422
423 if( SharedData )
424 {
425 UnmapViewOfFile(SharedData);
426 NtClose(UlongToHandle(lpProtocolInfo->dwServiceFlags3));
427 }
428 else
429 {
430 if( Socket && Socket->SharedData )
431 HeapFree(GlobalHeap, 0, Socket->SharedData);
432 }
433
434 if( Socket )
435 HeapFree(GlobalHeap, 0, Socket);
436
437 if( EABuffer )
438 HeapFree(GlobalHeap, 0, EABuffer);
439
440 if( lpErrno )
441 *lpErrno = Status;
442
443 return INVALID_SOCKET;
444}
445
446
447INT
448WSPAPI
452 OUT LPWSAPROTOCOL_INFOW lpProtocolInfo,
453 OUT LPINT lpErrno)
454{
455 HANDLE hProcess, hDuplicatedSharedData, hDuplicatedHandle;
456 PSOCKET_INFORMATION Socket;
457 PSOCK_SHARED_INFO pSharedData, pOldSharedData;
458 BOOL bDuplicated;
459
460 if (Handle == INVALID_SOCKET)
462 Socket = GetSocketStructure(Handle);
463 if( !Socket )
464 {
465 if( lpErrno )
466 *lpErrno = WSAENOTSOCK;
467 return SOCKET_ERROR;
468 }
471
472 /* It is a not yet duplicated socket, so map the memory, copy the SharedData and free heap */
474 {
476 NULL,
478 0,
479 (sizeof(SOCK_SHARED_INFO) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1),
480 NULL);
483 pSharedData = MapViewOfFile(Socket->SharedDataHandle,
485 0,
486 0,
487 sizeof(SOCK_SHARED_INFO));
488
489 RtlCopyMemory(pSharedData, Socket->SharedData, sizeof(SOCK_SHARED_INFO));
490 pOldSharedData = Socket->SharedData;
491 Socket->SharedData = pSharedData;
492 HeapFree(GlobalHeap, 0, pOldSharedData);
493 }
494 /* Duplicate the handles for the new process */
495 bDuplicated = DuplicateHandle(GetCurrentProcess(),
496 Socket->SharedDataHandle,
497 hProcess,
498 (LPHANDLE)&hDuplicatedSharedData,
499 0,
500 FALSE,
502 if (!bDuplicated)
503 {
506 }
507 bDuplicated = DuplicateHandle(GetCurrentProcess(),
508 (HANDLE)Socket->Handle,
509 hProcess,
510 (LPHANDLE)&hDuplicatedHandle,
511 0,
512 FALSE,
515 if( !bDuplicated )
517
518
519 if (!lpProtocolInfo)
521
522 RtlCopyMemory(lpProtocolInfo, &Socket->ProtocolInfo, sizeof(*lpProtocolInfo));
523
524 lpProtocolInfo->iAddressFamily = Socket->SharedData->AddressFamily;
525 lpProtocolInfo->iProtocol = Socket->SharedData->Protocol;
526 lpProtocolInfo->iSocketType = Socket->SharedData->SocketType;
527 lpProtocolInfo->dwServiceFlags3 = HandleToUlong(hDuplicatedSharedData);
528 lpProtocolInfo->dwServiceFlags4 = HandleToUlong(hDuplicatedHandle);
529
530 if( lpErrno )
531 *lpErrno = NO_ERROR;
532
533 return NO_ERROR;
534}
535
536INT
538{
539 switch (Status)
540 {
541 case STATUS_CANT_WAIT:
542 return WSAEWOULDBLOCK;
543
544 case STATUS_TIMEOUT:
545 return WSAETIMEDOUT;
546
547 case STATUS_SUCCESS:
548 return NO_ERROR;
549
551 return WSAECONNRESET;
552
554 return WSAESHUTDOWN;
555
556 case STATUS_PENDING:
557 return WSA_IO_PENDING;
558
561 return WSAEMSGSIZE;
562
563 case STATUS_NO_MEMORY:
565 return WSAENOBUFS;
566
568 return WSAENOTCONN;
569
571 return WSAEAFNOSUPPORT;
572
574 return WSAEADDRNOTAVAIL;
575
578 return WSAECONNREFUSED;
579
581 return WSAENETUNREACH;
582
584 return WSAEHOSTUNREACH;
585
587 return WSAEINVAL;
588
589 case STATUS_CANCELLED:
591
593 return WSAEADDRINUSE;
594
596 return WSAECONNABORTED;
597
599 return WSAEFAULT;
600
602 return WSAEACCES;
603
605 return WSAEOPNOTSUPP;
606
607 default:
608 ERR("MSAFD: Unhandled NTSTATUS value: 0x%x\n", Status);
609 return WSAENETDOWN;
610 }
611}
612
613VOID
615 _In_ HANDLE hObject)
616{
618
619 for (;;)
620 {
623 break;
624 }
625}
626
627/*
628 * FUNCTION: Closes an open socket
629 * ARGUMENTS:
630 * s = Socket descriptor
631 * lpErrno = Address of buffer for error information
632 * RETURNS:
633 * NO_ERROR, or SOCKET_ERROR if the socket could not be closed
634 */
635INT
636WSPAPI
638 OUT LPINT lpErrno)
639{
641 PSOCKET_INFORMATION Socket = NULL, CurrentSocket;
644 AFD_DISCONNECT_INFO DisconnectInfo;
645 SOCKET_STATE OldState;
646 LONG LingerWait = -1;
647 DWORD References;
648
649 /* Get the Socket Structure associate to this Socket*/
650 Socket = GetSocketStructure(Handle);
651 if (!Socket)
652 {
653 if (lpErrno) *lpErrno = WSAENOTSOCK;
654 return SOCKET_ERROR;
655 }
656
657 /* HACK: Allow APC to be processed */
658 SleepEx(0, TRUE);
659
660 if (Socket->HelperEvents & WSH_NOTIFY_CLOSE)
661 {
662 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
663 Socket->Handle,
664 Socket->TdiAddressHandle,
665 Socket->TdiConnectionHandle,
667
668 if (Status)
669 {
670 ERR("WSHNotify failed. Error 0x%#x\n", Status);
671 if (lpErrno) *lpErrno = Status;
672 return SOCKET_ERROR;
673 }
674 }
675
676 /* If a Close is already in Process, give up */
677 if (Socket->SharedData->State == SocketClosed)
678 {
679 WARN("Socket is closing.\n");
680 if (lpErrno) *lpErrno = WSAENOTSOCK;
681 return SOCKET_ERROR;
682 }
683
684 /* Create the Wait Event */
687 NULL,
689 FALSE);
690 if (!NT_SUCCESS(Status))
691 {
692 ERR("NtCreateEvent failed: 0x%08x\n", Status);
693 return SOCKET_ERROR;
694 }
695
696 /* Decrement reference count on SharedData */
697 References = InterlockedDecrement(&Socket->SharedData->RefCount);
698 if (References)
699 goto ok;
700
701 /* Set the state to close */
702 OldState = Socket->SharedData->State;
703 Socket->SharedData->State = SocketClosed;
704
705 /* If SO_LINGER is ON and the Socket is connected, we need to disconnect */
706 /* FIXME: Should we do this on Datagram Sockets too? */
707 if ((OldState == SocketConnected) && (Socket->SharedData->LingerData.l_onoff))
708 {
709 ULONG SendsInProgress;
710 ULONG SleepWait;
711
712 /* We need to respect the timeout */
713 SleepWait = 100;
714 LingerWait = Socket->SharedData->LingerData.l_linger * 1000;
715
716 /* Loop until no more sends are pending, within the timeout */
717 while (LingerWait)
718 {
719 /* Find out how many Sends are in Progress */
720 if (GetSocketInformation(Socket,
722 NULL,
723 &SendsInProgress,
724 NULL,
725 NULL,
726 NULL))
727 {
728 /* Bail out if anything but NO_ERROR */
729 LingerWait = 0;
730 break;
731 }
732
733 /* Bail out if no more sends are pending */
734 if (!SendsInProgress)
735 {
736 LingerWait = -1;
737 break;
738 }
739
740 /*
741 * We have to execute a sleep, so it's kind of like
742 * a block. If the socket is Nonblock, we cannot
743 * go on since asynchronous operation is expected
744 * and we cannot offer it
745 */
746 if (Socket->SharedData->NonBlocking)
747 {
748 WARN("Would block!\n");
750 Socket->SharedData->State = OldState;
751 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
752 return SOCKET_ERROR;
753 }
754
755 /* Now we can sleep, and decrement the linger wait */
756 /*
757 * FIXME: It seems Windows does some funky acceleration
758 * since the waiting seems to be longer and longer. I
759 * don't think this improves performance so much, so we
760 * wait a fixed time instead.
761 */
762 Sleep(SleepWait);
763 LingerWait -= SleepWait;
764 }
765 }
766
767 if (OldState == SocketConnected)
768 {
769 if (LingerWait <= 0)
770 {
771 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
772 DisconnectInfo.DisconnectType = LingerWait < 0 ? AFD_DISCONNECT_SEND : AFD_DISCONNECT_ABORT;
773
774 if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData->SendShutdown)) ||
775 ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData->ReceiveShutdown)))
776 {
777 /* Send IOCTL */
779 SockEvent,
780 NULL,
781 NULL,
784 &DisconnectInfo,
785 sizeof(DisconnectInfo),
786 NULL,
787 0);
788
789 /* Wait for return */
790 if (Status == STATUS_PENDING)
791 {
794 }
795 }
796 }
797 }
798
799 /* Cleanup Time! */
800 Socket->HelperContext = NULL;
801 Socket->SharedData->AsyncDisabledEvents = -1;
802 NtClose(Socket->TdiAddressHandle);
803 Socket->TdiAddressHandle = NULL;
805 Socket->TdiConnectionHandle = NULL;
806ok:
808 if (SocketListHead == Socket)
809 {
811 }
812 else
813 {
814 CurrentSocket = SocketListHead;
815 while (CurrentSocket->NextSocket)
816 {
817 if (CurrentSocket->NextSocket == Socket)
818 {
819 CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket;
820 break;
821 }
822
823 CurrentSocket = CurrentSocket->NextSocket;
824 }
825 }
827
828 /* Close the handle */
831
833 {
834 /* It is a duplicated socket, so unmap the memory */
836 NtClose(Socket->SharedDataHandle);
837 Socket->SharedData = NULL;
838 }
839 if( !References && Socket->SharedData )
840 {
841 HeapFree(GlobalHeap, 0, Socket->SharedData);
842 }
843 HeapFree(GlobalHeap, 0, Socket);
844 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
845}
846
847
848/*
849 * FUNCTION: Associates a local address with a socket
850 * ARGUMENTS:
851 * s = Socket descriptor
852 * name = Pointer to local address
853 * namelen = Length of name
854 * lpErrno = Address of buffer for error information
855 * RETURNS:
856 * 0, or SOCKET_ERROR if the socket could not be bound
857 */
858INT
859WSPAPI
861 const struct sockaddr *SocketAddress,
862 int SocketAddressLength,
863 LPINT lpErrno)
864{
865 IO_STATUS_BLOCK IOSB;
866 PAFD_BIND_DATA BindData;
867 PSOCKET_INFORMATION Socket = NULL;
869 SOCKADDR_INFO SocketInfo;
871 ULONG connectSize;
872
873 /* Get the Socket Structure associate to this Socket*/
874 Socket = GetSocketStructure(Handle);
875 if (!Socket)
876 {
877 if (lpErrno) *lpErrno = WSAENOTSOCK;
878 return SOCKET_ERROR;
879 }
880 if (Socket->SharedData->State != SocketOpen)
881 {
882 if (lpErrno) *lpErrno = WSAEINVAL;
883 return SOCKET_ERROR;
884 }
885 if (!SocketAddress || SocketAddressLength < Socket->SharedData->SizeOfLocalAddress)
886 {
887 if (lpErrno) *lpErrno = WSAEINVAL;
888 return SOCKET_ERROR;
889 }
890
891 /* Get Address Information */
892 Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
893 SocketAddressLength,
894 &SocketInfo);
895
896 if (SocketInfo.AddressInfo == SockaddrAddressInfoBroadcast && !Socket->SharedData->Broadcast)
897 {
898 if (lpErrno) *lpErrno = WSAEADDRNOTAVAIL;
899 return SOCKET_ERROR;
900 }
901
904 NULL,
906 FALSE);
907
908 if (!NT_SUCCESS(Status))
909 {
910 return SOCKET_ERROR;
911 }
912
913 connectSize = FIELD_OFFSET(AFD_BIND_DATA, Address.Address[SocketAddressLength]);
914
915 /* See below */
916 BindData = HeapAlloc(GlobalHeap, 0, connectSize);
917 if (!BindData)
918 {
920 }
921
922 /* Set up Address in TDI Format */
923 BindData->Address.TAAddressCount = 1;
924 BindData->Address.Address[0].AddressLength = (USHORT)(SocketAddressLength - sizeof(SocketAddress->sa_family));
925 BindData->Address.Address[0].AddressType = SocketAddress->sa_family;
926 RtlCopyMemory (BindData->Address.Address[0].Address,
927 SocketAddress->sa_data,
928 SocketAddressLength - sizeof(SocketAddress->sa_family));
929
930 /* Set the Share Type */
931 if (Socket->SharedData->ExclusiveAddressUse)
932 {
933 BindData->ShareType = AFD_SHARE_EXCLUSIVE;
934 }
935 else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard)
936 {
937 BindData->ShareType = AFD_SHARE_WILDCARD;
938 }
939 else if (Socket->SharedData->ReuseAddresses)
940 {
941 BindData->ShareType = AFD_SHARE_REUSE;
942 }
943 else
944 {
945 BindData->ShareType = AFD_SHARE_UNIQUE;
946 }
947
948 /* Send IOCTL */
950 SockEvent,
951 NULL,
952 NULL,
953 &IOSB,
955 BindData,
956 connectSize,
957 BindData,
958 connectSize);
959
960 /* Wait for return */
961 if (Status == STATUS_PENDING)
962 {
964 Status = IOSB.Status;
965 }
966
968 HeapFree(GlobalHeap, 0, BindData);
969
971 if (Status != STATUS_SUCCESS)
972 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
973
974 /* Set up Socket Data */
975 Socket->SharedData->State = SocketBound;
976 Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
977
979 {
980 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
981 Socket->Handle,
982 Socket->TdiAddressHandle,
983 Socket->TdiConnectionHandle,
985
986 if (Status)
987 {
988 if (lpErrno) *lpErrno = Status;
989 return SOCKET_ERROR;
990 }
991 }
992
993 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
994}
995
996int
997WSPAPI
999 int Backlog,
1000 LPINT lpErrno)
1001{
1002 IO_STATUS_BLOCK IOSB;
1003 AFD_LISTEN_DATA ListenData;
1004 PSOCKET_INFORMATION Socket = NULL;
1007
1008 /* Get the Socket Structure associate to this Socket*/
1009 Socket = GetSocketStructure(Handle);
1010 if (!Socket)
1011 {
1012 if (lpErrno) *lpErrno = WSAENOTSOCK;
1013 return SOCKET_ERROR;
1014 }
1015
1016 if (Socket->SharedData->Listening)
1017 return NO_ERROR;
1018
1021 NULL,
1023 FALSE);
1024
1025 if( !NT_SUCCESS(Status) )
1026 return SOCKET_ERROR;
1027
1028 /* Set Up Listen Structure */
1029 ListenData.UseSAN = FALSE;
1031 ListenData.Backlog = Backlog;
1032
1033 /* Send IOCTL */
1035 SockEvent,
1036 NULL,
1037 NULL,
1038 &IOSB,
1040 &ListenData,
1041 sizeof(ListenData),
1042 NULL,
1043 0);
1044
1045 /* Wait for return */
1046 if (Status == STATUS_PENDING)
1047 {
1049 Status = IOSB.Status;
1050 }
1051
1052 NtClose( SockEvent );
1053
1055 if (Status != STATUS_SUCCESS)
1056 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1057
1058 /* Set to Listening */
1059 Socket->SharedData->Listening = TRUE;
1060
1061 if (Socket->HelperEvents & WSH_NOTIFY_LISTEN)
1062 {
1063 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1064 Socket->Handle,
1065 Socket->TdiAddressHandle,
1066 Socket->TdiConnectionHandle,
1068
1069 if (Status)
1070 {
1071 if (lpErrno) *lpErrno = Status;
1072 return SOCKET_ERROR;
1073 }
1074 }
1075
1076 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1077}
1078
1079
1080int
1081WSPAPI
1082WSPSelect(IN int nfds,
1083 IN OUT fd_set *readfds OPTIONAL,
1084 IN OUT fd_set *writefds OPTIONAL,
1085 IN OUT fd_set *exceptfds OPTIONAL,
1086 IN const struct timeval *timeout OPTIONAL,
1087 OUT LPINT lpErrno)
1088{
1089 IO_STATUS_BLOCK IOSB;
1090 PAFD_POLL_INFO PollInfo;
1093 ULONG PollBufferSize;
1094 PVOID PollBuffer;
1095 ULONG i, j = 0, x;
1098 PSOCKET_INFORMATION Socket;
1099 SOCKET Handle;
1100 ULONG Events;
1101 fd_set selectfds;
1102
1103 /* Find out how many sockets we have, and how large the buffer needs
1104 * to be */
1105 FD_ZERO(&selectfds);
1106 if (readfds != NULL)
1107 {
1108 for (i = 0; i < readfds->fd_count; i++)
1109 {
1110 FD_SET(readfds->fd_array[i], &selectfds);
1111 }
1112 }
1113 if (writefds != NULL)
1114 {
1115 for (i = 0; i < writefds->fd_count; i++)
1116 {
1117 FD_SET(writefds->fd_array[i], &selectfds);
1118 }
1119 }
1120 if (exceptfds != NULL)
1121 {
1122 for (i = 0; i < exceptfds->fd_count; i++)
1123 {
1124 FD_SET(exceptfds->fd_array[i], &selectfds);
1125 }
1126 }
1127
1128 HandleCount = selectfds.fd_count;
1129
1130 if ( HandleCount == 0 )
1131 {
1132 WARN("No handles! Returning SOCKET_ERROR\n", HandleCount);
1133 if (lpErrno) *lpErrno = WSAEINVAL;
1134 return SOCKET_ERROR;
1135 }
1136
1137 PollBufferSize = sizeof(*PollInfo) + ((HandleCount - 1) * sizeof(AFD_HANDLE));
1138
1139 TRACE("HandleCount: %u BufferSize: %u\n", HandleCount, PollBufferSize);
1140
1141 /* Convert Timeout to NT Format */
1142 if (timeout == NULL)
1143 {
1144 Timeout.u.LowPart = -1;
1145 Timeout.u.HighPart = 0x7FFFFFFF;
1146 TRACE("Infinite timeout\n");
1147 }
1148 else
1149 {
1151 ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000), -10000);
1152 /* Negative timeouts are illegal. Since the kernel represents an
1153 * incremental timeout as a negative number, we check for a positive
1154 * result.
1155 */
1156 if (Timeout.QuadPart > 0)
1157 {
1158 if (lpErrno) *lpErrno = WSAEINVAL;
1159 return SOCKET_ERROR;
1160 }
1161 TRACE("Timeout: Orig %d.%06d kernel %d\n",
1162 timeout->tv_sec, timeout->tv_usec,
1163 Timeout.u.LowPart);
1164 }
1165
1168 NULL,
1170 FALSE);
1171
1172 if(!NT_SUCCESS(Status))
1173 {
1174 if (lpErrno)
1175 *lpErrno = WSAEFAULT;
1176
1177 ERR("NtCreateEvent failed, 0x%08x\n", Status);
1178 return SOCKET_ERROR;
1179 }
1180
1181 /* Allocate */
1182 PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
1183
1184 if (!PollBuffer)
1185 {
1186 if (lpErrno)
1187 *lpErrno = WSAEFAULT;
1189 return SOCKET_ERROR;
1190 }
1191
1192 PollInfo = (PAFD_POLL_INFO)PollBuffer;
1193
1194 RtlZeroMemory( PollInfo, PollBufferSize );
1195
1196 /* Number of handles for AFD to Check */
1197 PollInfo->Exclusive = FALSE;
1198 PollInfo->Timeout = Timeout;
1199
1200 for (i = 0; i < selectfds.fd_count; i++)
1201 {
1202 PollInfo->Handles[i].Handle = selectfds.fd_array[i];
1203 }
1204 if (readfds != NULL) {
1205 for (i = 0; i < readfds->fd_count; i++)
1206 {
1207 for (j = 0; j < HandleCount; j++)
1208 {
1209 if (PollInfo->Handles[j].Handle == readfds->fd_array[i])
1210 break;
1211 }
1212 if (j >= HandleCount)
1213 {
1214 ERR("Error while counting readfds %ld > %ld\n", j, HandleCount);
1215 if (lpErrno) *lpErrno = WSAEFAULT;
1216 HeapFree(GlobalHeap, 0, PollBuffer);
1218 return SOCKET_ERROR;
1219 }
1220 Socket = GetSocketStructure(readfds->fd_array[i]);
1221 if (!Socket)
1222 {
1223 ERR("Invalid socket handle provided in readfds %d\n", readfds->fd_array[i]);
1224 if (lpErrno) *lpErrno = WSAENOTSOCK;
1225 HeapFree(GlobalHeap, 0, PollBuffer);
1227 return SOCKET_ERROR;
1228 }
1229 PollInfo->Handles[j].Events |= AFD_EVENT_RECEIVE |
1234 //if (Socket->SharedData->OobInline != 0)
1235 // PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
1236 }
1237 }
1238 if (writefds != NULL)
1239 {
1240 for (i = 0; i < writefds->fd_count; i++)
1241 {
1242 for (j = 0; j < HandleCount; j++)
1243 {
1244 if (PollInfo->Handles[j].Handle == writefds->fd_array[i])
1245 break;
1246 }
1247 if (j >= HandleCount)
1248 {
1249 ERR("Error while counting writefds %ld > %ld\n", j, HandleCount);
1250 if (lpErrno) *lpErrno = WSAEFAULT;
1251 HeapFree(GlobalHeap, 0, PollBuffer);
1253 return SOCKET_ERROR;
1254 }
1255 Socket = GetSocketStructure(writefds->fd_array[i]);
1256 if (!Socket)
1257 {
1258 ERR("Invalid socket handle provided in writefds %d\n", writefds->fd_array[i]);
1259 if (lpErrno) *lpErrno = WSAENOTSOCK;
1260 HeapFree(GlobalHeap, 0, PollBuffer);
1262 return SOCKET_ERROR;
1263 }
1264 PollInfo->Handles[j].Handle = writefds->fd_array[i];
1265 PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
1266 if (Socket->SharedData->NonBlocking != 0)
1267 PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT;
1268 }
1269 }
1270 if (exceptfds != NULL)
1271 {
1272 for (i = 0; i < exceptfds->fd_count; i++)
1273 {
1274 for (j = 0; j < HandleCount; j++)
1275 {
1276 if (PollInfo->Handles[j].Handle == exceptfds->fd_array[i])
1277 break;
1278 }
1279 if (j > HandleCount)
1280 {
1281 ERR("Error while counting exceptfds %ld > %ld\n", j, HandleCount);
1282 if (lpErrno) *lpErrno = WSAEFAULT;
1283 HeapFree(GlobalHeap, 0, PollBuffer);
1285 return SOCKET_ERROR;
1286 }
1287 Socket = GetSocketStructure(exceptfds->fd_array[i]);
1288 if (!Socket)
1289 {
1290 TRACE("Invalid socket handle provided in exceptfds %d\n", exceptfds->fd_array[i]);
1291 if (lpErrno) *lpErrno = WSAENOTSOCK;
1292 HeapFree(GlobalHeap, 0, PollBuffer);
1294 return SOCKET_ERROR;
1295 }
1296 PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
1297 if (Socket->SharedData->OobInline == 0)
1298 PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
1299 if (Socket->SharedData->NonBlocking != 0)
1300 PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT_FAIL;
1301 }
1302 }
1303
1304 PollInfo->HandleCount = HandleCount;
1305 PollBufferSize = FIELD_OFFSET(AFD_POLL_INFO, Handles) + PollInfo->HandleCount * sizeof(AFD_HANDLE);
1306
1307 /* Send IOCTL */
1309 SockEvent,
1310 NULL,
1311 NULL,
1312 &IOSB,
1314 PollInfo,
1315 PollBufferSize,
1316 PollInfo,
1317 PollBufferSize);
1318
1319 TRACE("DeviceIoControlFile => %x\n", Status);
1320
1321 /* Wait for Completion */
1322 if (Status == STATUS_PENDING)
1323 {
1325 Status = IOSB.Status;
1326 }
1327
1328 /* Clear the Structures */
1329 if( readfds )
1330 FD_ZERO(readfds);
1331 if( writefds )
1332 FD_ZERO(writefds);
1333 if( exceptfds )
1334 FD_ZERO(exceptfds);
1335
1336 /* Loop through return structure */
1337 HandleCount = PollInfo->HandleCount;
1338
1339 /* Return in FDSET Format */
1340 for (i = 0; i < HandleCount; i++)
1341 {
1342 Events = PollInfo->Handles[i].Events;
1343 Handle = PollInfo->Handles[i].Handle;
1344 for(x = 1; x; x<<=1)
1345 {
1346 Socket = GetSocketStructure(Handle);
1347 if (!Socket)
1348 {
1349 TRACE("Invalid socket handle found %d\n", Handle);
1350 if (lpErrno) *lpErrno = WSAENOTSOCK;
1351 HeapFree(GlobalHeap, 0, PollBuffer);
1353 return SOCKET_ERROR;
1354 }
1355 switch (Events & x)
1356 {
1357 case AFD_EVENT_RECEIVE:
1359 case AFD_EVENT_ABORT:
1360 case AFD_EVENT_ACCEPT:
1361 case AFD_EVENT_CLOSE:
1362 TRACE("Event %x on handle %x\n",
1363 Events,
1364 Handle);
1365 if ((Events & x) == AFD_EVENT_DISCONNECT || (Events & x) == AFD_EVENT_CLOSE)
1367 if ((Events & x) == AFD_EVENT_ABORT)
1369 if( readfds )
1370 FD_SET(Handle, readfds);
1371 break;
1372 case AFD_EVENT_SEND:
1373 TRACE("Event %x on handle %x\n",
1374 Events,
1375 Handle);
1376 if (writefds)
1377 FD_SET(Handle, writefds);
1378 break;
1379 case AFD_EVENT_CONNECT:
1380 TRACE("Event %x on handle %x\n",
1381 Events,
1382 Handle);
1383 if( writefds && Socket->SharedData->NonBlocking != 0 )
1384 FD_SET(Handle, writefds);
1385 break;
1387 TRACE("Event %x on handle %x\n",
1388 Events,
1389 Handle);
1390 if( readfds && Socket->SharedData->OobInline != 0 )
1391 FD_SET(Handle, readfds);
1392 if( exceptfds && Socket->SharedData->OobInline == 0 )
1393 FD_SET(Handle, exceptfds);
1394 break;
1396 TRACE("Event %x on handle %x\n",
1397 Events,
1398 Handle);
1399 if( exceptfds && Socket->SharedData->NonBlocking != 0 )
1400 FD_SET(Handle, exceptfds);
1401 break;
1402 }
1403 }
1404 }
1405
1406 HeapFree( GlobalHeap, 0, PollBuffer );
1407 NtClose( SockEvent );
1408
1409 if( lpErrno )
1410 {
1411 switch( IOSB.Status )
1412 {
1413 case STATUS_SUCCESS:
1414 case STATUS_TIMEOUT:
1415 *lpErrno = 0;
1416 break;
1417 default:
1418 *lpErrno = WSAEINVAL;
1419 break;
1420 }
1421 TRACE("*lpErrno = %x\n", *lpErrno);
1422 }
1423
1424 HandleCount = (readfds ? readfds->fd_count : 0) +
1425 (writefds && writefds != readfds ? writefds->fd_count : 0) +
1426 (exceptfds && exceptfds != readfds && exceptfds != writefds ? exceptfds->fd_count : 0);
1427
1428 TRACE("%d events\n", HandleCount);
1429
1430 return HandleCount;
1431}
1432
1433DWORD
1435{
1436 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
1437 union
1438 {
1439 FILETIME ft;
1440 ULONGLONG ll;
1441 } u1970, Time;
1442
1444 SystemTimeToFileTime(&st1970, &u1970.ft);
1445 return (DWORD)((Time.ll - u1970.ll) / 10000000ULL);
1446}
1447
1449SOCKET
1450WSPAPI
1453 _Out_writes_bytes_to_opt_(*addrlen, *addrlen) struct sockaddr FAR *SocketAddress,
1454 _Inout_opt_ LPINT SocketAddressLength,
1455 _In_opt_ LPCONDITIONPROC lpfnCondition,
1456 _In_opt_ DWORD_PTR dwCallbackData,
1457 _Out_ LPINT lpErrno)
1458{
1459 IO_STATUS_BLOCK IOSB;
1460 PAFD_RECEIVED_ACCEPT_DATA ListenReceiveData;
1461 AFD_ACCEPT_DATA AcceptData;
1462 AFD_DEFER_ACCEPT_DATA DeferData;
1463 AFD_PENDING_ACCEPT_DATA PendingAcceptData;
1464 PSOCKET_INFORMATION Socket = NULL;
1466 struct fd_set ReadSet;
1467 struct timeval Timeout;
1468 PVOID PendingData = NULL;
1469 ULONG PendingDataLength = 0;
1470 PVOID CalleeDataBuffer;
1471 WSABUF CallerData, CalleeID, CallerID, CalleeData;
1473 GROUP GroupID = 0;
1474 ULONG CallBack;
1476 PSOCKET_INFORMATION AcceptSocketInfo;
1477 UCHAR ReceiveBuffer[0x1A];
1479
1480 /* Get the Socket Structure associate to this Socket*/
1481 Socket = GetSocketStructure(Handle);
1482 if (!Socket)
1483 {
1484 if (lpErrno) *lpErrno = WSAENOTSOCK;
1485 return SOCKET_ERROR;
1486 }
1487 if (!Socket->SharedData->Listening)
1488 {
1489 if (lpErrno) *lpErrno = WSAEINVAL;
1490 return SOCKET_ERROR;
1491 }
1492 if ((SocketAddress && !SocketAddressLength) ||
1493 (SocketAddressLength && !SocketAddress) ||
1494 (SocketAddressLength && *SocketAddressLength < sizeof(SOCKADDR)))
1495 {
1496 if (lpErrno) *lpErrno = WSAEFAULT;
1497 return INVALID_SOCKET;
1498 }
1499
1502 NULL,
1504 FALSE);
1505
1506 if( !NT_SUCCESS(Status) )
1507 {
1508 return SOCKET_ERROR;
1509 }
1510
1511 /* Dynamic Structure...ugh */
1512 ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
1513
1514 /* If this is non-blocking, make sure there's something for us to accept */
1515 if (Socket->SharedData->NonBlocking)
1516 {
1517 FD_ZERO(&ReadSet);
1518 FD_SET(Socket->Handle, &ReadSet);
1519 Timeout.tv_sec=0;
1520 Timeout.tv_usec=0;
1521
1522 if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
1523 {
1525 return SOCKET_ERROR;
1526 }
1527
1528 if (ReadSet.fd_array[0] != Socket->Handle)
1529 {
1531 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
1532 return SOCKET_ERROR;
1533 }
1534 }
1535
1536 /* Send IOCTL */
1538 SockEvent,
1539 NULL,
1540 NULL,
1541 &IOSB,
1543 NULL,
1544 0,
1545 ListenReceiveData,
1546 0xA + sizeof(*ListenReceiveData));
1547
1548 /* Wait for return */
1549 if (Status == STATUS_PENDING)
1550 {
1552 Status = IOSB.Status;
1553 }
1554
1555 if (!NT_SUCCESS(Status))
1556 {
1557 NtClose( SockEvent );
1558 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1559 }
1560
1561 if (lpfnCondition != NULL)
1562 {
1563 if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECT_DATA) != 0)
1564 {
1565 /* Find out how much data is pending */
1566 PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1567 PendingAcceptData.ReturnSize = TRUE;
1568
1569 /* Send IOCTL */
1571 SockEvent,
1572 NULL,
1573 NULL,
1574 &IOSB,
1576 &PendingAcceptData,
1577 sizeof(PendingAcceptData),
1578 &PendingAcceptData,
1579 sizeof(PendingAcceptData));
1580
1581 /* Wait for return */
1582 if (Status == STATUS_PENDING)
1583 {
1585 Status = IOSB.Status;
1586 }
1587
1588 if (!NT_SUCCESS(Status))
1589 {
1590 NtClose( SockEvent );
1591 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1592 }
1593
1594 /* How much data to allocate */
1595 PendingDataLength = IOSB.Information;
1596
1597 if (PendingDataLength)
1598 {
1599 /* Allocate needed space */
1600 PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
1601 if (!PendingData)
1602 {
1604 }
1605
1606 /* We want the data now */
1607 PendingAcceptData.ReturnSize = FALSE;
1608
1609 /* Send IOCTL */
1611 SockEvent,
1612 NULL,
1613 NULL,
1614 &IOSB,
1616 &PendingAcceptData,
1617 sizeof(PendingAcceptData),
1618 PendingData,
1619 PendingDataLength);
1620
1621 /* Wait for return */
1622 if (Status == STATUS_PENDING)
1623 {
1625 Status = IOSB.Status;
1626 }
1627
1628 if (!NT_SUCCESS(Status))
1629 {
1630 NtClose( SockEvent );
1631 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1632 }
1633 }
1634 }
1635
1636 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1637 {
1638 /* I don't support this yet */
1639 }
1640
1641 /* Build Callee ID */
1642 CalleeID.buf = (PVOID)Socket->LocalAddress;
1643 CalleeID.len = Socket->SharedData->SizeOfLocalAddress;
1644
1646 if (!RemoteAddress)
1647 {
1649 }
1650
1651 /* Set up Address in SOCKADDR Format */
1653 &ListenReceiveData->Address.Address[0].AddressType,
1654 sizeof(*RemoteAddress));
1655
1656 /* Build Caller ID */
1657 CallerID.buf = (PVOID)RemoteAddress;
1658 CallerID.len = sizeof(*RemoteAddress);
1659
1660 /* Build Caller Data */
1661 CallerData.buf = PendingData;
1662 CallerData.len = PendingDataLength;
1663
1664 /* Check if socket supports Conditional Accept */
1665 if (Socket->SharedData->UseDelayedAcceptance != 0)
1666 {
1667 /* Allocate Buffer for Callee Data */
1668 CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
1669 if (!CalleeDataBuffer) {
1671 }
1672 CalleeData.buf = CalleeDataBuffer;
1673 CalleeData.len = 4096;
1674 }
1675 else
1676 {
1677 /* Nothing */
1678 CalleeData.buf = 0;
1679 CalleeData.len = 0;
1680 }
1681
1682 /* Call the Condition Function */
1683 CallBack = (lpfnCondition)(&CallerID,
1684 CallerData.buf == NULL ? NULL : &CallerData,
1685 NULL,
1686 NULL,
1687 &CalleeID,
1688 CalleeData.buf == NULL ? NULL : &CalleeData,
1689 &GroupID,
1690 dwCallbackData);
1691
1692 if (((CallBack == CF_ACCEPT) && GroupID) != 0)
1693 {
1694 /* TBD: Check for Validity */
1695 }
1696
1697 if (CallBack == CF_ACCEPT)
1698 {
1699 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1700 {
1701 /* I don't support this yet */
1702 }
1703 if (CalleeData.buf)
1704 {
1705 // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0
1706 }
1707 }
1708 else
1709 {
1710 /* Callback rejected. Build Defer Structure */
1711 DeferData.SequenceNumber = ListenReceiveData->SequenceNumber;
1712 DeferData.RejectConnection = (CallBack == CF_REJECT);
1713
1714 /* Send IOCTL */
1716 SockEvent,
1717 NULL,
1718 NULL,
1719 &IOSB,
1721 &DeferData,
1722 sizeof(DeferData),
1723 NULL,
1724 0);
1725
1726 /* Wait for return */
1727 if (Status == STATUS_PENDING)
1728 {
1730 Status = IOSB.Status;
1731 }
1732
1733 NtClose( SockEvent );
1734
1735 if (!NT_SUCCESS(Status))
1736 {
1737 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1738 }
1739
1740 if (CallBack == CF_REJECT )
1741 {
1742 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1743 return SOCKET_ERROR;
1744 }
1745 else
1746 {
1747 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1748 return SOCKET_ERROR;
1749 }
1750 }
1751 }
1752
1753 /* Create a new Socket */
1755 Socket->SharedData->SocketType,
1756 Socket->SharedData->Protocol,
1757 &Socket->ProtocolInfo,
1758 GroupID,
1759 Socket->SharedData->CreateFlags,
1760 lpErrno);
1762 return SOCKET_ERROR;
1763
1764 /* Set up the Accept Structure */
1765 AcceptData.ListenHandle = (HANDLE)AcceptSocket;
1766 AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1767
1768 /* Send IOCTL to Accept */
1770 SockEvent,
1771 NULL,
1772 NULL,
1773 &IOSB,
1775 &AcceptData,
1776 sizeof(AcceptData),
1777 NULL,
1778 0);
1779
1780 /* Wait for return */
1781 if (Status == STATUS_PENDING)
1782 {
1784 Status = IOSB.Status;
1785 }
1786
1788 if (!NT_SUCCESS(Status))
1789 {
1791 WSPCloseSocket( AcceptSocket, lpErrno );
1792 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1793 }
1794
1795 AcceptSocketInfo = GetSocketStructure(AcceptSocket);
1796 if (!AcceptSocketInfo)
1797 {
1799 WSPCloseSocket( AcceptSocket, lpErrno );
1801 }
1802
1803 AcceptSocketInfo->SharedData->State = SocketConnected;
1804 AcceptSocketInfo->SharedData->ConnectTime = GetCurrentTimeInSeconds();
1805 AcceptSocketInfo->SharedData->NonBlocking = Socket->SharedData->NonBlocking;
1806
1807 /* Return Address in SOCKADDR FORMAT */
1808 if( SocketAddress )
1809 {
1810 RtlCopyMemory (SocketAddress,
1811 &ListenReceiveData->Address.Address[0].AddressType,
1812 sizeof(*RemoteAddress));
1813 if( SocketAddressLength )
1814 *SocketAddressLength = sizeof(*RemoteAddress);
1815 }
1816
1817 NtClose( SockEvent );
1818
1819 /* Re-enable Async Event */
1821
1822 TRACE("Socket %x\n", AcceptSocket);
1823
1825 {
1826 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1827 Socket->Handle,
1828 Socket->TdiAddressHandle,
1829 Socket->TdiConnectionHandle,
1831
1832 if (Status)
1833 {
1834 if (lpErrno) *lpErrno = Status;
1835 return SOCKET_ERROR;
1836 }
1837 }
1838
1839 if (lpErrno) *lpErrno = NO_ERROR;
1840
1841 /* Return Socket */
1842 return AcceptSocket;
1843}
1844
1845static
1846VOID
1847NTAPI
1852{
1854
1855 TRACE("MsafdConnectAPC(%p %lx %lx)\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information);
1856
1858 if (!Socket)
1859 {
1860 // FIXME: Socket is closed before this APC could run
1862 return;
1863 }
1864
1867 {
1868 Socket->SharedData->State = SocketConnected;
1871 }
1872
1873 /* Re-enable Async Event */
1875
1876 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
1878
1880 {
1881 Socket->HelperData->WSHNotify(Socket->HelperContext,
1882 Socket->Handle,
1883 Socket->TdiAddressHandle,
1884 Socket->TdiConnectionHandle,
1886 }
1888 {
1889 Socket->HelperData->WSHNotify(Socket->HelperContext,
1890 Socket->Handle,
1891 Socket->TdiAddressHandle,
1892 Socket->TdiConnectionHandle,
1894 }
1895
1897}
1898
1899int
1900WSPAPI
1902 const struct sockaddr * SocketAddress,
1903 int SocketAddressLength,
1904 LPWSABUF lpCallerData,
1905 LPWSABUF lpCalleeData,
1906 LPQOS lpSQOS,
1907 LPQOS lpGQOS,
1908 LPINT lpErrno)
1909{
1910 IO_STATUS_BLOCK DummyIOSB;
1911 PIO_STATUS_BLOCK IOSB = &DummyIOSB;
1912 PAFD_CONNECT_INFO ConnectInfo = NULL;
1913 PSOCKET_INFORMATION Socket;
1915 INT Errno;
1916 ULONG ConnectDataLength;
1917 ULONG InConnectDataLength;
1919 int SocketDataLength;
1920 PMSAFD_CONNECT_APC_CONTEXT APCContext = NULL;
1921 PIO_APC_ROUTINE APCFunction = NULL;
1922 UCHAR Buffer[128];
1923
1924 TRACE("WSPConnect(%x)\n", Handle);
1925
1926 /* Get the Socket Structure associate to this Socket*/
1927 Socket = GetSocketStructure(Handle);
1928 if (!Socket)
1929 {
1930 if (lpErrno) *lpErrno = WSAENOTSOCK;
1931 return SOCKET_ERROR;
1932 }
1933
1934 /* Bind us First */
1935 if (Socket->SharedData->State == SocketOpen)
1936 {
1937 INT BindAddressLength;
1938 PSOCKADDR BindAddress;
1939 INT BindError;
1940
1941 /* Get the Wildcard Address */
1942 BindAddressLength = Socket->HelperData->MaxWSAddressLength;
1943 BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength);
1944 if (!BindAddress)
1945 {
1947 }
1949 BindAddress,
1950 &BindAddressLength);
1951 /* Bind it */
1952 BindError = WSPBind(Handle, BindAddress, BindAddressLength, lpErrno);
1953 HeapFree(GetProcessHeap(), 0, BindAddress);
1954 if (BindError == SOCKET_ERROR)
1955 return SOCKET_ERROR;
1956 }
1957
1960 NULL,
1962 FALSE);
1963 if (!NT_SUCCESS(Status))
1964 return SOCKET_ERROR;
1965
1966 /* Set the Connect Data */
1967 if (lpCallerData != NULL)
1968 {
1969 ConnectDataLength = lpCallerData->len;
1971 SockEvent,
1972 NULL,
1973 NULL,
1974 IOSB,
1976 lpCallerData->buf,
1977 ConnectDataLength,
1978 NULL,
1979 0);
1980 /* Wait for return */
1981 if (Status == STATUS_PENDING)
1982 {
1984 Status = IOSB->Status;
1985 }
1986
1987 if (Status != STATUS_SUCCESS)
1988 goto Leave;
1989 }
1990
1991 /* Calculate the size of SocketAddress->sa_data */
1992 SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
1993
1994 ConnectInfo = (PAFD_CONNECT_INFO)Buffer;
1995
1996 int connectionInfoSize = FIELD_OFFSET(AFD_CONNECT_INFO, RemoteAddress.Address[0].Address[SocketDataLength]);
1997
1998 if (connectionInfoSize > 128)
1999 {
2000 *lpErrno = WSAEFAULT;
2001 return SOCKET_ERROR;
2002 }
2003
2004 /* Set up Address in TDI Format */
2005 ConnectInfo->RemoteAddress.TAAddressCount = 1;
2006 ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
2007 ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
2009 SocketAddress->sa_data,
2010 SocketDataLength);
2011
2012 /*
2013 * Disable FD_WRITE and FD_CONNECT
2014 * The latter fixes a race condition where the FD_CONNECT is re-enabled
2015 * at the end of this function right after the Async Thread disables it.
2016 * This should only happen at the *next* WSPConnect
2017 */
2018 if (Socket->SharedData->AsyncEvents & FD_CONNECT)
2019 {
2021 }
2022
2023 /* Tell AFD that we want Connection Data back, have it allocate a buffer */
2024 if (lpCalleeData != NULL)
2025 {
2026 InConnectDataLength = lpCalleeData->len;
2028 SockEvent,
2029 NULL,
2030 NULL,
2031 IOSB,
2033 &InConnectDataLength,
2034 sizeof(InConnectDataLength),
2035 NULL,
2036 0);
2037
2038 /* Wait for return */
2039 if (Status == STATUS_PENDING)
2040 {
2042 Status = IOSB->Status;
2043 }
2044
2045 if (Status != STATUS_SUCCESS)
2046 goto Leave;
2047 }
2048
2049 /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */
2050 ConnectInfo->Root = 0;
2051 ConnectInfo->UseSAN = FALSE;
2052 ConnectInfo->Unknown = 0;
2053
2054 /* Verify if we should use APC */
2055 if (Socket->SharedData->NonBlocking)
2056 {
2057 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
2058 if (!APCContext)
2059 {
2060 ERR("Not enough memory for APC Context\n");
2062 goto Leave;
2063 }
2064 APCContext->lpSocket = Handle;
2065 APCFunction = &MsafdConnectAPC;
2066
2067 IOSB = &APCContext->IoStatusBlock;
2068 }
2069
2070 IOSB->Status = STATUS_PENDING;
2071 IOSB->Information = 0;
2072
2073 /* Send IOCTL */
2075 APCFunction ? NULL : SockEvent,
2076 APCFunction,
2077 APCContext,
2078 IOSB,
2080 ConnectInfo,
2081 connectionInfoSize,
2082 NULL,
2083 0);
2084 if (Socket->SharedData->NonBlocking)
2085 {
2086 if (Status == STATUS_PENDING)
2087 {
2088 Status = STATUS_CANT_WAIT; // WSAEWOULDBLOCK
2089 goto Leave;
2090 }
2091 else
2092 {
2093 /* HACK: Allow APC to be processed */
2094 SleepEx(0, TRUE);
2095 }
2096 }
2097 else
2098 {
2099 /* Wait for completion if blocking */
2100 if (Status == STATUS_PENDING)
2101 {
2103 Status = IOSB->Status;
2104 }
2105
2107 if (Status != STATUS_SUCCESS)
2108 goto Leave;
2109
2110 Socket->SharedData->State = SocketConnected;
2111 Socket->TdiConnectionHandle = (HANDLE)IOSB->Information;
2113 }
2114
2115 /* Get any pending connect data */
2116 if (lpCalleeData != NULL && Status == STATUS_SUCCESS)
2117 {
2118 IOSB = &DummyIOSB;
2120 SockEvent,
2121 NULL,
2122 NULL,
2123 IOSB,
2125 NULL,
2126 0,
2127 lpCalleeData->buf,
2128 lpCalleeData->len);
2129 /* Wait for return */
2130 if (Status == STATUS_PENDING)
2131 {
2133 Status = IOSB->Status;
2134 }
2135 }
2136
2137Leave:
2138 TRACE("Ending %lx\n", Status);
2139
2141
2142 /* Re-enable Async Event */
2144
2145 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
2147
2149 {
2150 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2151 Socket->Handle,
2152 Socket->TdiAddressHandle,
2153 Socket->TdiConnectionHandle,
2155
2156 if (Errno)
2157 {
2158 if (lpErrno) *lpErrno = Errno;
2159 return SOCKET_ERROR;
2160 }
2161 }
2163 {
2164 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2165 Socket->Handle,
2166 Socket->TdiAddressHandle,
2167 Socket->TdiConnectionHandle,
2169
2170 if (Errno)
2171 {
2172 if (lpErrno) *lpErrno = Errno;
2173 return SOCKET_ERROR;
2174 }
2175 }
2176
2177 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
2178}
2179
2180BOOL
2181WSPAPI
2184 _In_ const struct sockaddr *SocketAddress,
2185 _In_ int SocketAddressLength,
2186 _In_ PVOID lpSendBuffer,
2187 _In_ DWORD dwSendDataLength,
2188 _Out_ LPDWORD lpdwBytesSent,
2190{
2191 IO_STATUS_BLOCK DummyIOSB;
2192 PIO_STATUS_BLOCK IOSB = &DummyIOSB;
2193 PAFD_SUPER_CONNECT_INFO ConnectInfo = NULL;
2194 PSOCKET_INFORMATION Socket;
2196 int SocketDataLength;
2197 UCHAR Buffer[128];
2198
2199 if (!lpOverlapped)
2200 {
2202 return FALSE;
2203 }
2204
2205 if (!lpSendBuffer && dwSendDataLength)
2206 {
2208 return FALSE;
2209 }
2210
2211 /* Get the Socket Structure associate to this Socket*/
2212 Socket = GetSocketStructure(Handle);
2213 if (!Socket)
2214 {
2216 return FALSE;
2217 }
2218
2219
2220 /* Cannot call on connectionless socket */
2221 if (SocketAddressLength > ARRAYSIZE(Buffer) - sizeof(AFD_CONNECT_INFO) || Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS)
2222 {
2224 return SOCKET_ERROR;
2225 }
2226
2227 if (Socket->SharedData->State == SocketOpen)
2228 {
2229 /* Socket already must be bound */
2231 return FALSE;
2232 }
2233
2234 ConnectInfo = (PAFD_SUPER_CONNECT_INFO)Buffer;
2235 ConnectInfo->SanActive = FALSE;
2236
2237 /* Calculate the size of SocketAddress->sa_data */
2238 SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
2239
2240 /* Set up Address in TDI Format */
2241 ConnectInfo->RemoteAddress.TAAddressCount = 1;
2242 ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
2243 ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
2245 SocketAddress->sa_data,
2246 SocketDataLength);
2247
2248 /*
2249 * Disable FD_WRITE and FD_CONNECT.
2250 * The latter fixes a race condition where the FD_CONNECT is re-enabled
2251 * at the end of this function right after the Async Thread disables it.
2252 * This should only happen at the *next* WSPConnect.
2253 */
2254 if (Socket->SharedData->AsyncEvents & FD_CONNECT)
2255 {
2257 }
2258
2260 IOSB->Status = STATUS_PENDING;
2261
2262 /* Send IOCTL */
2264 lpOverlapped->hEvent,
2265 NULL,
2266 lpOverlapped->hEvent ? NULL : lpOverlapped,
2267 IOSB,
2269 ConnectInfo,
2270 FIELD_OFFSET(AFD_SUPER_CONNECT_INFO, RemoteAddress.Address[0].Address[SocketDataLength]),
2271 lpSendBuffer,
2272 dwSendDataLength);
2273
2275
2276 return Status == STATUS_SUCCESS;
2277}
2278
2279int
2280WSPAPI
2282 int HowTo,
2283 LPINT lpErrno)
2284
2285{
2286 IO_STATUS_BLOCK IOSB;
2287 AFD_DISCONNECT_INFO DisconnectInfo;
2288 PSOCKET_INFORMATION Socket = NULL;
2291
2292 TRACE("Called\n");
2293
2294 /* Get the Socket Structure associate to this Socket*/
2295 Socket = GetSocketStructure(Handle);
2296 if (!Socket)
2297 {
2298 if (lpErrno) *lpErrno = WSAENOTSOCK;
2299 return SOCKET_ERROR;
2300 }
2301
2304 NULL,
2306 FALSE);
2307
2308 if( !NT_SUCCESS(Status) )
2309 return SOCKET_ERROR;
2310
2311 /* Set AFD Disconnect Type */
2312 switch (HowTo)
2313 {
2314 case SD_RECEIVE:
2315 DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
2316 Socket->SharedData->ReceiveShutdown = TRUE;
2317 break;
2318 case SD_SEND:
2319 DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
2320 Socket->SharedData->SendShutdown = TRUE;
2321 break;
2322 case SD_BOTH:
2324 Socket->SharedData->ReceiveShutdown = TRUE;
2325 Socket->SharedData->SendShutdown = TRUE;
2326 break;
2327 }
2328
2329 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1000000);
2330
2331 /* Send IOCTL */
2333 SockEvent,
2334 NULL,
2335 NULL,
2336 &IOSB,
2338 &DisconnectInfo,
2339 sizeof(DisconnectInfo),
2340 NULL,
2341 0);
2342
2343 /* Wait for return */
2344 if (Status == STATUS_PENDING)
2345 {
2347 Status = IOSB.Status;
2348 }
2349
2350 TRACE("Ending\n");
2351
2352 NtClose( SockEvent );
2353
2355 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
2356}
2357
2358
2359INT
2360WSPAPI
2363 IN OUT LPINT NameLength,
2364 OUT LPINT lpErrno)
2365{
2366 IO_STATUS_BLOCK IOSB;
2367 ULONG TdiAddressSize;
2368 PTDI_ADDRESS_INFO TdiAddress;
2369 PTRANSPORT_ADDRESS SocketAddress;
2370 PSOCKET_INFORMATION Socket = NULL;
2373
2374 /* Get the Socket Structure associate to this Socket*/
2375 Socket = GetSocketStructure(Handle);
2376 if (!Socket)
2377 {
2378 if (lpErrno) *lpErrno = WSAENOTSOCK;
2379 return SOCKET_ERROR;
2380 }
2381
2382 if (!Name || !NameLength)
2383 {
2384 if (lpErrno) *lpErrno = WSAEFAULT;
2385 return SOCKET_ERROR;
2386 }
2387
2390 NULL,
2392 FALSE);
2393
2394 if( !NT_SUCCESS(Status) )
2395 return SOCKET_ERROR;
2396
2397 /* Allocate a buffer for the address */
2398 TdiAddressSize =
2400 TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2401
2402 if ( TdiAddress == NULL )
2403 {
2404 NtClose( SockEvent );
2405 if (lpErrno) *lpErrno = WSAENOBUFS;
2406 return SOCKET_ERROR;
2407 }
2408
2409 SocketAddress = &TdiAddress->Address;
2410
2411 /* Send IOCTL */
2413 SockEvent,
2414 NULL,
2415 NULL,
2416 &IOSB,
2418 NULL,
2419 0,
2420 TdiAddress,
2421 TdiAddressSize);
2422
2423 /* Wait for return */
2424 if (Status == STATUS_PENDING)
2425 {
2427 Status = IOSB.Status;
2428 }
2429
2430 NtClose( SockEvent );
2431
2432 if (NT_SUCCESS(Status))
2433 {
2434 if (*NameLength >= Socket->SharedData->SizeOfLocalAddress)
2435 {
2436 Name->sa_family = SocketAddress->Address[0].AddressType;
2437 RtlCopyMemory (Name->sa_data,
2438 SocketAddress->Address[0].Address,
2439 SocketAddress->Address[0].AddressLength);
2440 *NameLength = Socket->SharedData->SizeOfLocalAddress;
2441 TRACE("NameLength %d Address: %x Port %x\n",
2442 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2443 ((struct sockaddr_in *)Name)->sin_port);
2444 HeapFree(GlobalHeap, 0, TdiAddress);
2445 return 0;
2446 }
2447 else
2448 {
2449 HeapFree(GlobalHeap, 0, TdiAddress);
2450 if (lpErrno) *lpErrno = WSAEFAULT;
2451 return SOCKET_ERROR;
2452 }
2453 }
2454
2455 HeapFree(GlobalHeap, 0, TdiAddress);
2456
2457 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2458}
2459
2460
2461INT
2462WSPAPI
2465 IN OUT LPINT NameLength,
2466 OUT LPINT lpErrno)
2467{
2468 IO_STATUS_BLOCK IOSB;
2469 ULONG TdiAddressSize;
2470 PTRANSPORT_ADDRESS SocketAddress;
2471 PSOCKET_INFORMATION Socket = NULL;
2474
2475 /* Get the Socket Structure associate to this Socket*/
2476 Socket = GetSocketStructure(s);
2477 if (!Socket)
2478 {
2479 if (lpErrno) *lpErrno = WSAENOTSOCK;
2480 return SOCKET_ERROR;
2481 }
2482
2483 if (Socket->SharedData->State != SocketConnected)
2484 {
2485 if (lpErrno) *lpErrno = WSAENOTCONN;
2486 return SOCKET_ERROR;
2487 }
2488
2489 if (!Name || !NameLength)
2490 {
2491 if (lpErrno) *lpErrno = WSAEFAULT;
2492 return SOCKET_ERROR;
2493 }
2494
2497 NULL,
2499 FALSE);
2500
2501 if( !NT_SUCCESS(Status) )
2502 return SOCKET_ERROR;
2503
2504 /* Allocate a buffer for the address */
2505 TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress;
2506 SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2507
2508 if ( SocketAddress == NULL )
2509 {
2510 NtClose( SockEvent );
2511 if (lpErrno) *lpErrno = WSAENOBUFS;
2512 return SOCKET_ERROR;
2513 }
2514
2515 /* Send IOCTL */
2517 SockEvent,
2518 NULL,
2519 NULL,
2520 &IOSB,
2522 NULL,
2523 0,
2524 SocketAddress,
2525 TdiAddressSize);
2526
2527 /* Wait for return */
2528 if (Status == STATUS_PENDING)
2529 {
2531 Status = IOSB.Status;
2532 }
2533
2534 NtClose( SockEvent );
2535
2536 if (NT_SUCCESS(Status))
2537 {
2538 if (*NameLength >= Socket->SharedData->SizeOfRemoteAddress)
2539 {
2540 Name->sa_family = SocketAddress->Address[0].AddressType;
2541 RtlCopyMemory (Name->sa_data,
2542 SocketAddress->Address[0].Address,
2543 SocketAddress->Address[0].AddressLength);
2544 *NameLength = Socket->SharedData->SizeOfRemoteAddress;
2545 TRACE("NameLength %d Address: %x Port %x\n",
2546 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2547 ((struct sockaddr_in *)Name)->sin_port);
2548 HeapFree(GlobalHeap, 0, SocketAddress);
2549 return 0;
2550 }
2551 else
2552 {
2553 HeapFree(GlobalHeap, 0, SocketAddress);
2554 if (lpErrno) *lpErrno = WSAEFAULT;
2555 return SOCKET_ERROR;
2556 }
2557 }
2558
2559 HeapFree(GlobalHeap, 0, SocketAddress);
2560
2561 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2562}
2563
2564INT
2565WSPAPI
2568 IN LPVOID lpvInBuffer,
2569 IN DWORD cbInBuffer,
2570 OUT LPVOID lpvOutBuffer,
2571 IN DWORD cbOutBuffer,
2572 OUT LPDWORD lpcbBytesReturned,
2574 IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
2575 IN LPWSATHREADID lpThreadId,
2576 OUT LPINT lpErrno)
2577{
2578 PSOCKET_INFORMATION Socket = NULL;
2579 BOOL NeedsCompletion = lpOverlapped != NULL;
2580 BOOLEAN NonBlocking;
2581 INT Errno = NO_ERROR, Ret = SOCKET_ERROR;
2582 DWORD cbRet = 0;
2583
2584 /* Get the Socket Structure associate to this Socket*/
2585 Socket = GetSocketStructure(Handle);
2586 if (!Socket)
2587 {
2588 if(lpErrno)
2589 *lpErrno = WSAENOTSOCK;
2590 return SOCKET_ERROR;
2591 }
2592
2593 if (!lpcbBytesReturned && !lpOverlapped)
2594 {
2595 if(lpErrno)
2596 *lpErrno = WSAEFAULT;
2597 return SOCKET_ERROR;
2598 }
2599
2600 switch( dwIoControlCode )
2601 {
2602 case FIONBIO:
2603 if( cbInBuffer < sizeof(INT) || IS_INTRESOURCE(lpvInBuffer) )
2604 {
2605 Errno = WSAEFAULT;
2606 break;
2607 }
2608 NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
2609 /* Don't allow to go in blocking mode if WSPAsyncSelect or WSPEventSelect is pending */
2610 if (!NonBlocking)
2611 {
2612 /* If there is an WSPAsyncSelect pending, fail with WSAEINVAL */
2613 if (Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents))
2614 {
2615 Errno = WSAEINVAL;
2616 break;
2617 }
2618 /* If there is an WSPEventSelect pending, fail with WSAEINVAL */
2619 if (Socket->NetworkEvents)
2620 {
2621 Errno = WSAEINVAL;
2622 break;
2623 }
2624 }
2625 Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
2626 NeedsCompletion = FALSE;
2627 Errno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL, lpOverlapped, lpCompletionRoutine);
2628 if (Errno == NO_ERROR)
2629 Ret = NO_ERROR;
2630 break;
2631 case FIONREAD:
2632 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2633 {
2634 cbRet = sizeof(ULONG);
2635 Errno = WSAEFAULT;
2636 break;
2637 }
2638 if (cbOutBuffer < sizeof(ULONG))
2639 {
2640 Errno = WSAEINVAL;
2641 break;
2642 }
2643 NeedsCompletion = FALSE;
2644 Errno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL, lpOverlapped, lpCompletionRoutine);
2645 if (Errno == NO_ERROR)
2646 {
2647 cbRet = sizeof(ULONG);
2648 Ret = NO_ERROR;
2649 }
2650 break;
2651 case SIOCATMARK:
2652 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2653 {
2654 cbRet = sizeof(BOOL);
2655 Errno = WSAEFAULT;
2656 break;
2657 }
2658 if (cbOutBuffer < sizeof(BOOL))
2659 {
2660 Errno = WSAEINVAL;
2661 break;
2662 }
2663 if (Socket->SharedData->SocketType != SOCK_STREAM)
2664 {
2665 Errno = WSAEINVAL;
2666 break;
2667 }
2668
2669 /* FIXME: Return false if OOBINLINE is true for now
2670 We should MSG_PEEK|MSG_OOB check with driver
2671 */
2672 *(BOOL*)lpvOutBuffer = !Socket->SharedData->OobInline;
2673
2674 cbRet = sizeof(BOOL);
2675 Errno = NO_ERROR;
2676 Ret = NO_ERROR;
2677 break;
2679 if (cbOutBuffer == 0)
2680 {
2681 cbRet = sizeof(PVOID);
2682 Errno = WSAEFAULT;
2683 break;
2684 }
2685
2686 if (cbInBuffer < sizeof(GUID) ||
2687 cbOutBuffer < sizeof(PVOID))
2688 {
2689 Errno = WSAEINVAL;
2690 break;
2691 }
2692
2693 {
2694 GUID AcceptExGUID = WSAID_ACCEPTEX;
2695 GUID ConnectExGUID = WSAID_CONNECTEX;
2696 GUID DisconnectExGUID = WSAID_DISCONNECTEX;
2697 GUID GetAcceptExSockaddrsGUID = WSAID_GETACCEPTEXSOCKADDRS;
2698
2699 if (IsEqualGUID(&AcceptExGUID, lpvInBuffer))
2700 {
2701 *((PVOID *)lpvOutBuffer) = WSPAcceptEx;
2702 cbRet = sizeof(PVOID);
2703 Errno = NO_ERROR;
2704 Ret = NO_ERROR;
2705 }
2706 else if (IsEqualGUID(&ConnectExGUID, lpvInBuffer))
2707 {
2708 *((PVOID *)lpvOutBuffer) = WSPConnectEx;
2709 cbRet = sizeof(PVOID);
2710 Errno = NO_ERROR;
2711 Ret = NO_ERROR;
2712 }
2713 else if (IsEqualGUID(&DisconnectExGUID, lpvInBuffer))
2714 {
2715 *((PVOID *)lpvOutBuffer) = WSPDisconnectEx;
2716 cbRet = sizeof(PVOID);
2717 Errno = NO_ERROR;
2718 Ret = NO_ERROR;
2719 }
2720 else if (IsEqualGUID(&GetAcceptExSockaddrsGUID, lpvInBuffer))
2721 {
2722 *((PVOID *)lpvOutBuffer) = WSPGetAcceptExSockaddrs;
2723 cbRet = sizeof(PVOID);
2724 Errno = NO_ERROR;
2725 /* See CORE-14966 and associated commits.
2726 * Original line below was 'Ret = NO_ERROR:'.
2727 * This caused winetest ws2_32:sock to hang.
2728 * This new Ret value allows the test to complete. */
2729 ERR("SIO_GET_EXTENSION_FUNCTION_POINTER UNIMPLEMENTED\n");
2730 Ret = SOCKET_ERROR;
2731 }
2732 else
2733 {
2734 ERR("Querying unknown extension function: %x\n", ((GUID*)lpvInBuffer)->Data1);
2735 Errno = WSAEOPNOTSUPP;
2736 }
2737 }
2738
2739 break;
2741 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2742 {
2743 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2744 Errno = WSAEFAULT;
2745 break;
2746 }
2747 if (cbOutBuffer < sizeof(INT))
2748 {
2749 Errno = WSAEINVAL;
2750 break;
2751 }
2752
2753 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2754
2755 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->iAddressCount = 1;
2756
2757 if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress)))
2758 {
2759 Errno = WSAEFAULT;
2760 break;
2761 }
2762
2763 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->SharedData->WSLocalAddress);
2764 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->SharedData->WSLocalAddress;
2765
2766 Errno = NO_ERROR;
2767 Ret = NO_ERROR;
2768 break;
2769 default:
2770 Errno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
2771 Handle,
2772 Socket->TdiAddressHandle,
2773 Socket->TdiConnectionHandle,
2775 lpvInBuffer,
2776 cbInBuffer,
2777 lpvOutBuffer,
2778 cbOutBuffer,
2779 &cbRet,
2781 lpCompletionRoutine,
2782 &NeedsCompletion);
2783
2784 if (Errno == NO_ERROR)
2785 Ret = NO_ERROR;
2786 break;
2787 }
2788 if (lpOverlapped && NeedsCompletion)
2789 {
2790 lpOverlapped->Internal = Errno;
2791 lpOverlapped->InternalHigh = cbRet;
2792 if (lpCompletionRoutine != NULL)
2793 {
2794 lpCompletionRoutine(Errno, cbRet, lpOverlapped, 0);
2795 }
2796 if (lpOverlapped->hEvent)
2797 SetEvent(lpOverlapped->hEvent);
2799 {
2800 ERR("PostQueuedCompletionStatus failed %d\n", GetLastError());
2801 }
2802 return NO_ERROR;
2803 }
2804 if (lpErrno)
2805 *lpErrno = Errno;
2806 if (lpcbBytesReturned)
2807 *lpcbBytesReturned = cbRet;
2808 return Ret;
2809}
2810
2811
2812INT
2813WSPAPI
2815 IN INT Level,
2816 IN INT OptionName,
2817 OUT CHAR FAR* OptionValue,
2818 IN OUT LPINT OptionLength,
2819 OUT LPINT lpErrno)
2820{
2821 PSOCKET_INFORMATION Socket = NULL;
2822 PVOID Buffer;
2824 BOOL BoolBuffer;
2825 DWORD DwordBuffer;
2826 INT Errno;
2827
2828 TRACE("Called\n");
2829
2830 /* Get the Socket Structure associate to this Socket*/
2831 Socket = GetSocketStructure(Handle);
2832 if (Socket == NULL)
2833 {
2834 if (lpErrno) *lpErrno = WSAENOTSOCK;
2835 return SOCKET_ERROR;
2836 }
2837 if (!OptionLength || !OptionValue)
2838 {
2839 if (lpErrno) *lpErrno = WSAEFAULT;
2840 return SOCKET_ERROR;
2841 }
2842
2843 switch (Level)
2844 {
2845 case SOL_SOCKET:
2846 switch (OptionName)
2847 {
2848 case SO_TYPE:
2849 Buffer = &Socket->SharedData->SocketType;
2850 BufferSize = sizeof(INT);
2851 break;
2852
2853 case SO_RCVBUF:
2855 BufferSize = sizeof(ULONG);
2856 break;
2857
2858 case SO_SNDBUF:
2860 BufferSize = sizeof(ULONG);
2861 break;
2862
2863 case SO_ACCEPTCONN:
2864 BoolBuffer = Socket->SharedData->Listening;
2865 Buffer = &BoolBuffer;
2866 BufferSize = sizeof(BOOL);
2867 break;
2868
2869 case SO_BROADCAST:
2870 BoolBuffer = Socket->SharedData->Broadcast;
2871 Buffer = &BoolBuffer;
2872 BufferSize = sizeof(BOOL);
2873 break;
2874
2875 case SO_DEBUG:
2876 BoolBuffer = Socket->SharedData->Debug;
2877 Buffer = &BoolBuffer;
2878 BufferSize = sizeof(BOOL);
2879 break;
2880
2881 case SO_DONTLINGER:
2882 BoolBuffer = (Socket->SharedData->LingerData.l_onoff == 0);
2883 Buffer = &BoolBuffer;
2884 BufferSize = sizeof(BOOL);
2885 break;
2886
2887 case SO_LINGER:
2888 if (Socket->SharedData->SocketType == SOCK_DGRAM)
2889 {
2890 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
2891 return SOCKET_ERROR;
2892 }
2893 Buffer = &Socket->SharedData->LingerData;
2894 BufferSize = sizeof(struct linger);
2895 break;
2896
2897 case SO_OOBINLINE:
2898 BoolBuffer = (Socket->SharedData->OobInline != 0);
2899 Buffer = &BoolBuffer;
2900 BufferSize = sizeof(BOOL);
2901 break;
2902
2903 case SO_KEEPALIVE:
2904 case SO_DONTROUTE:
2905 /* These guys go directly to the helper */
2906 goto SendToHelper;
2907
2909 BoolBuffer = (Socket->SharedData->UseDelayedAcceptance != 0);
2910 Buffer = &BoolBuffer;
2911 BufferSize = sizeof(BOOL);
2912 break;
2913
2914 case SO_REUSEADDR:
2915 BoolBuffer = (Socket->SharedData->ReuseAddresses != 0);
2916 Buffer = &BoolBuffer;
2917 BufferSize = sizeof(BOOL);
2918 break;
2919
2921 BoolBuffer = (Socket->SharedData->ExclusiveAddressUse != 0);
2922 Buffer = &BoolBuffer;
2923 BufferSize = sizeof(BOOL);
2924 break;
2925
2926 case SO_ERROR:
2927 Buffer = &Socket->SharedData->SocketLastError;
2928 BufferSize = sizeof(INT);
2929 break;
2930
2931 case SO_CONNECT_TIME:
2932 DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
2933 Buffer = &DwordBuffer;
2934 BufferSize = sizeof(DWORD);
2935 break;
2936
2937 case SO_SNDTIMEO:
2938 Buffer = &Socket->SharedData->SendTimeout;
2939 BufferSize = sizeof(DWORD);
2940 break;
2941 case SO_RCVTIMEO:
2942 Buffer = &Socket->SharedData->RecvTimeout;
2943 BufferSize = sizeof(DWORD);
2944 break;
2945 case SO_PROTOCOL_INFOW:
2946 Buffer = &Socket->ProtocolInfo;
2947 BufferSize = sizeof(Socket->ProtocolInfo);
2948 break;
2949
2950 case SO_GROUP_ID:
2951 case SO_GROUP_PRIORITY:
2952 case SO_MAX_MSG_SIZE:
2953
2954 default:
2955 DbgPrint("MSAFD: Get unknown optname %x\n", OptionName);
2956 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
2957 return SOCKET_ERROR;
2958 }
2959
2960 if (*OptionLength < BufferSize)
2961 {
2962 if (lpErrno) *lpErrno = WSAEFAULT;
2963 *OptionLength = BufferSize;
2964 return SOCKET_ERROR;
2965 }
2966 RtlCopyMemory(OptionValue, Buffer, BufferSize);
2967
2968 return 0;
2969
2970 default:
2971 if (lpErrno) *lpErrno = WSAEINVAL;
2972 return SOCKET_ERROR;
2973 }
2974
2975SendToHelper:
2976 Errno = Socket->HelperData->WSHGetSocketInformation(Socket->HelperContext,
2977 Handle,
2978 Socket->TdiAddressHandle,
2979 Socket->TdiConnectionHandle,
2980 Level,
2981 OptionName,
2982 OptionValue,
2983 (LPINT)OptionLength);
2984 if (lpErrno) *lpErrno = Errno;
2985 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
2986}
2987
2988static
2989INT
2990NTAPI
2993 _Out_ LPINT lpErrno)
2994{
2995 IO_STATUS_BLOCK DummyIOSB;
2996 PIO_STATUS_BLOCK IOSB = &DummyIOSB;
2998 SOCK_SHARED_INFO SharedData;
2999 AFD_TDI_HANDLE_DATA HandleData;
3002
3003 if (!Socket)
3004 {
3005 if (lpErrno) *lpErrno = WSAENOTSOCK;
3006 return SOCKET_ERROR;
3007 }
3008
3009 if (Socket->SharedData->State == SocketConnected)
3010 {
3011 return NO_ERROR;
3012 }
3013
3014 /* Get the socket context from AFD because when ConnectEx is used, this information is not updated. */
3017 NULL,
3019 FALSE);
3020 if (!NT_SUCCESS(Status))
3021 goto Quit;
3022
3024 SockEvent,
3025 NULL,
3026 NULL,
3027 IOSB,
3029 NULL,
3030 0,
3031 &SharedData,
3032 sizeof(SharedData));
3033
3034 if (Status == STATUS_PENDING)
3035 {
3037 Status = IOSB->Status;
3038 }
3039
3040 if (!NT_SUCCESS(Status))
3041 goto Quit;
3042
3044
3045 /* Get TDI handles from AFD */
3047 SockEvent,
3048 NULL,
3049 NULL,
3050 IOSB,
3052 &flags,
3053 sizeof(flags),
3054 &HandleData,
3055 sizeof(HandleData));
3056
3057 if (Status == STATUS_PENDING)
3058 {
3060 Status = IOSB->Status;
3061 }
3062
3063 /* Bail out if the socket was destroyed */
3064 if (!NT_SUCCESS(Status))
3065 goto Quit;
3066
3067 Socket->SharedData->State = SharedData.State;
3068
3069 if (SharedData.State == SocketConnected)
3070 {
3071 /* Socket is now connected, update usermode msafd socket structure, same as the end of WSPConnect */
3072 Socket->TdiConnectionHandle = HandleData.TdiConnectionHandle;
3073 Socket->TdiAddressHandle = HandleData.TdiAddressHandle;
3074 Socket->SharedData->ConnectTime = SharedData.ConnectTime;
3075
3076 /* Re-enable Async Event */
3078
3079 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
3081
3082 Socket->HelperData->WSHNotify(Socket->HelperContext,
3083 Socket->Handle,
3084 Socket->TdiAddressHandle,
3085 Socket->TdiConnectionHandle,
3087 }
3088
3090
3091Quit:
3092 if (Status == STATUS_SUCCESS)
3093 return NO_ERROR;
3094 if (lpErrno) *lpErrno = TranslateNtStatusError(Status);
3095 return SOCKET_ERROR;
3096}
3097
3098INT
3099WSPAPI
3101 IN SOCKET s,
3102 IN INT level,
3103 IN INT optname,
3104 IN CONST CHAR FAR* optval,
3105 IN INT optlen,
3106 OUT LPINT lpErrno)
3107{
3108 PSOCKET_INFORMATION Socket;
3109 INT Errno;
3110
3111 /* Get the Socket Structure associate to this Socket*/
3112 Socket = GetSocketStructure(s);
3113 if (Socket == NULL)
3114 {
3115 if (lpErrno) *lpErrno = WSAENOTSOCK;
3116 return SOCKET_ERROR;
3117 }
3118 if (!optval && optlen)
3119 {
3120 if (lpErrno) *lpErrno = WSAEFAULT;
3121 return SOCKET_ERROR;
3122 }
3123
3124
3125 /* FIXME: We should handle some more cases here */
3126 if (level == SOL_SOCKET)
3127 {
3128 switch (optname)
3129 {
3130 case SO_BROADCAST:
3131 if (optlen < sizeof(BOOL))
3132 {
3133 if (lpErrno) *lpErrno = WSAEFAULT;
3134 return SOCKET_ERROR;
3135 }
3136 Socket->SharedData->Broadcast = (*optval != 0) ? 1 : 0;
3137 return NO_ERROR;
3138
3139 case SO_OOBINLINE:
3140 if (optlen < sizeof(BOOL))
3141 {
3142 if (lpErrno) *lpErrno = WSAEFAULT;
3143 return SOCKET_ERROR;
3144 }
3145 Socket->SharedData->OobInline = (*optval != 0) ? 1 : 0;
3146 return NO_ERROR;
3147
3148 case SO_DONTLINGER:
3149 if (optlen < sizeof(BOOL))
3150 {
3151 if (lpErrno) *lpErrno = WSAEFAULT;
3152 return SOCKET_ERROR;
3153 }
3154 Socket->SharedData->LingerData.l_onoff = (*optval != 0) ? 0 : 1;
3155 return NO_ERROR;
3156
3157 case SO_REUSEADDR:
3158 if (optlen < sizeof(BOOL))
3159 {
3160 if (lpErrno) *lpErrno = WSAEFAULT;
3161 return SOCKET_ERROR;
3162 }
3163 Socket->SharedData->ReuseAddresses = (*optval != 0) ? 1 : 0;
3164 return NO_ERROR;
3165
3167 if (optlen < sizeof(BOOL))
3168 {
3169 if (lpErrno) *lpErrno = WSAEFAULT;
3170 return SOCKET_ERROR;
3171 }
3172 Socket->SharedData->ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
3173 return NO_ERROR;
3174
3175 case SO_LINGER:
3176 if (optlen < sizeof(struct linger))
3177 {
3178 if (lpErrno) *lpErrno = WSAEFAULT;
3179 return SOCKET_ERROR;
3180 }
3182 optval,
3183 sizeof(struct linger));
3184 return NO_ERROR;
3185
3186 case SO_SNDBUF:
3187 if (optlen < sizeof(ULONG))
3188 {
3189 if (lpErrno) *lpErrno = WSAEFAULT;
3190 return SOCKET_ERROR;
3191 }
3192
3193 SetSocketInformation(Socket,
3195 NULL,
3196 (PULONG)optval,
3197 NULL,
3198 NULL,
3199 NULL);
3200 GetSocketInformation(Socket,
3202 NULL,
3203 &Socket->SharedData->SizeOfSendBuffer,
3204 NULL,
3205 NULL,
3206 NULL);
3207
3208 return NO_ERROR;
3209
3210 case SO_RCVBUF:
3211 if (optlen < sizeof(ULONG))
3212 {
3213 if (lpErrno) *lpErrno = WSAEFAULT;
3214 return SOCKET_ERROR;
3215 }
3216
3217 /* FIXME: We should not have to limit the packet receive buffer size like this. workaround for CORE-15804 */
3218 if (*(PULONG)optval > 0x2000)
3219 *(PULONG)optval = 0x2000;
3220
3221 SetSocketInformation(Socket,
3223 NULL,
3224 (PULONG)optval,
3225 NULL,
3226 NULL,
3227 NULL);
3228 GetSocketInformation(Socket,
3230 NULL,
3231 &Socket->SharedData->SizeOfRecvBuffer,
3232 NULL,
3233 NULL,
3234 NULL);
3235
3236 return NO_ERROR;
3237
3238 case SO_UPDATE_CONNECT_CONTEXT:
3239 return MsafdUpdateConnectionContext(s, lpErrno);
3240
3241 case SO_ERROR:
3242 if (optlen < sizeof(INT))
3243 {
3244 if (lpErrno) *lpErrno = WSAEFAULT;
3245 return SOCKET_ERROR;
3246 }
3247
3249 optval,
3250 sizeof(INT));
3251 return NO_ERROR;
3252
3253 case SO_SNDTIMEO:
3254 if (optlen < sizeof(DWORD))
3255 {
3256 if (lpErrno) *lpErrno = WSAEFAULT;
3257 return SOCKET_ERROR;
3258 }
3259
3261 optval,
3262 sizeof(DWORD));
3263 return NO_ERROR;
3264
3265 case SO_RCVTIMEO:
3266 if (optlen < sizeof(DWORD))
3267 {
3268 if (lpErrno) *lpErrno = WSAEFAULT;
3269 return SOCKET_ERROR;
3270 }
3271
3273 optval,
3274 sizeof(DWORD));
3275 return NO_ERROR;
3276
3277 case SO_KEEPALIVE:
3278 case SO_DONTROUTE:
3279 /* These go directly to the helper dll */
3280 goto SendToHelper;
3281
3282 default:
3283 /* Obviously this is a hack */
3284 ERR("MSAFD: Set unknown optname %x\n", optname);
3285 return NO_ERROR;
3286 }
3287 }
3288
3289SendToHelper:
3290 Errno = Socket->HelperData->WSHSetSocketInformation(Socket->HelperContext,
3291 s,
3292 Socket->TdiAddressHandle,
3293 Socket->TdiConnectionHandle,
3294 level,
3295 optname,
3296 (PCHAR)optval,
3297 optlen);
3298 if (lpErrno) *lpErrno = Errno;
3299 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
3300}
3301
3302/*
3303 * FUNCTION: Initialize service provider for a client
3304 * ARGUMENTS:
3305 * wVersionRequested = Highest WinSock SPI version that the caller can use
3306 * lpWSPData = Address of WSPDATA structure to initialize
3307 * lpProtocolInfo = Pointer to structure that defines the desired protocol
3308 * UpcallTable = Pointer to upcall table of the WinSock DLL
3309 * lpProcTable = Address of procedure table to initialize
3310 * RETURNS:
3311 * Status of operation
3312 */
3314int
3315WSPAPI
3317 _In_ WORD wVersionRequested,
3318 _In_ LPWSPDATA lpWSPData,
3319 _In_ LPWSAPROTOCOL_INFOW lpProtocolInfo,
3320 _In_ WSPUPCALLTABLE UpcallTable,
3321 _Out_ LPWSPPROC_TABLE lpProcTable)
3322{
3324
3325 if (((LOBYTE(wVersionRequested) == 2) && (HIBYTE(wVersionRequested) < 2)) ||
3326 (LOBYTE(wVersionRequested) < 2))
3327 {
3328 ERR("WSPStartup NOT SUPPORTED for version 0x%X\n", wVersionRequested);
3329 return WSAVERNOTSUPPORTED;
3330 }
3331 else
3332 Status = NO_ERROR;
3333 /* FIXME: Enable all cases of WSPStartup status */
3334 Upcalls = UpcallTable;
3335
3336 if (Status == NO_ERROR)
3337 {
3338 lpProcTable->lpWSPAccept = WSPAccept;
3339 lpProcTable->lpWSPAddressToString = WSPAddressToString;
3340 lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;
3341 lpProcTable->lpWSPBind = WSPBind;
3342 lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;
3343 lpProcTable->lpWSPCleanup = WSPCleanup;
3344 lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
3345 lpProcTable->lpWSPConnect = WSPConnect;
3346 lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;
3347 lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;
3348 lpProcTable->lpWSPEventSelect = WSPEventSelect;
3349 lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;
3350 lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
3351 lpProcTable->lpWSPGetSockName = WSPGetSockName;
3352 lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;
3353 lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;
3354 lpProcTable->lpWSPIoctl = WSPIoctl;
3355 lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf;
3356 lpProcTable->lpWSPListen = WSPListen;
3357 lpProcTable->lpWSPRecv = WSPRecv;
3358 lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;
3359 lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
3360 lpProcTable->lpWSPSelect = WSPSelect;
3361 lpProcTable->lpWSPSend = WSPSend;
3362 lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;
3363 lpProcTable->lpWSPSendTo = WSPSendTo;
3364 lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
3365 lpProcTable->lpWSPShutdown = WSPShutdown;
3366 lpProcTable->lpWSPSocket = WSPSocket;
3367 lpProcTable->lpWSPStringToAddress = WSPStringToAddress;
3368 lpWSPData->wVersion = MAKEWORD(2, 2);
3369 lpWSPData->wHighVersion = MAKEWORD(2, 2);
3370 /* Save CatalogEntryId for all upcalls */
3371 CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
3372 }
3373
3374 TRACE("Status (%d).\n", Status);
3375 return Status;
3376}
3377
3378
3379INT
3380WSPAPI
3382 IN DWORD dwAddressLength,
3383 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
3384 OUT LPWSTR lpszAddressString,
3385 IN OUT LPDWORD lpdwAddressStringLength,
3386 OUT LPINT lpErrno)
3387{
3388 SIZE_T size;
3389 WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
3390 WCHAR *p;
3391
3392 if (!lpsaAddress || !lpszAddressString || !lpdwAddressStringLength)
3393 {
3394 if (lpErrno) *lpErrno = WSAEFAULT;
3395 return SOCKET_ERROR;
3396 }
3397
3398 switch (lpsaAddress->sa_family)
3399 {
3400 case AF_INET:
3401 if (dwAddressLength < sizeof(SOCKADDR_IN))
3402 {
3403 if (lpErrno) *lpErrno = WSAEINVAL;
3404 return SOCKET_ERROR;
3405 }
3407 L"%u.%u.%u.%u:%u",
3408 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 24 & 0xff),
3409 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 16 & 0xff),
3410 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 8 & 0xff),
3411 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) & 0xff),
3412 ntohs(((SOCKADDR_IN *)lpsaAddress)->sin_port));
3413
3414 p = wcschr(buffer, L':');
3415 if (!((SOCKADDR_IN *)lpsaAddress)->sin_port)
3416 {
3417 *p = 0;
3418 }
3419 break;
3420 default:
3421 if (lpErrno) *lpErrno = WSAEINVAL;
3422 return SOCKET_ERROR;
3423 }
3424
3425 size = wcslen(buffer) + 1;
3426
3427 if (*lpdwAddressStringLength < size)
3428 {
3429 *lpdwAddressStringLength = size;
3430 if (lpErrno) *lpErrno = WSAEFAULT;
3431 return SOCKET_ERROR;
3432 }
3433
3434 *lpdwAddressStringLength = size;
3435 wcscpy(lpszAddressString, buffer);
3436 return 0;
3437}
3438
3439INT
3440WSPAPI
3443 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
3444 OUT LPSOCKADDR lpAddress,
3445 IN OUT LPINT lpAddressLength,
3446 OUT LPINT lpErrno)
3447{
3448 int numdots = 0;
3449 USHORT port;
3450 LONG inetaddr = 0, ip_part;
3451 LPWSTR *bp = NULL;
3453
3454 if (!lpAddressLength || !lpAddress || !AddressString)
3455 {
3456 if (lpErrno) *lpErrno = WSAEINVAL;
3457 return SOCKET_ERROR;
3458 }
3459
3460 sockaddr = (SOCKADDR_IN *)lpAddress;
3461
3462 /* Set right address family */
3463 if (lpProtocolInfo != NULL)
3464 {
3465 sockaddr->sin_family = lpProtocolInfo->iAddressFamily;
3466 }
3467 else
3468 {
3469 sockaddr->sin_family = AddressFamily;
3470 }
3471
3472 /* Report size */
3473 if (AddressFamily == AF_INET)
3474 {
3475 if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN))
3476 {
3477 if (lpErrno) *lpErrno = WSAEFAULT;
3478 }
3479 else
3480 {
3481 // translate ip string to ip
3482
3483 /* Get ip number */
3484 bp = &AddressString;
3485 inetaddr = 0;
3486
3487 while (*bp < &AddressString[wcslen(AddressString)])
3488 {
3489 ip_part = wcstol(*bp, bp, 10);
3490 /* ip part number should be in range 0-255 */
3491 if (ip_part < 0 || ip_part > 255)
3492 {
3493 if (lpErrno) *lpErrno = WSAEINVAL;
3494 return SOCKET_ERROR;
3495 }
3496 inetaddr = (inetaddr << 8) + ip_part;
3497 /* we end on string end or port separator */
3498 if ((*bp)[0] == 0 || (*bp)[0] == L':')
3499 break;
3500 /* ip parts are dot separated. verify it */
3501 if ((*bp)[0] != L'.')
3502 {
3503 if (lpErrno) *lpErrno = WSAEINVAL;
3504 return SOCKET_ERROR;
3505 }
3506 /* count the dots */
3507 numdots++;
3508 /* move over the dot to next ip part */
3509 (*bp)++;
3510 }
3511
3512 /* check dots count */
3513 if (numdots != 3)
3514 {
3515 if (lpErrno) *lpErrno = WSAEINVAL;
3516 return SOCKET_ERROR;
3517 }
3518
3519 /* Get port number */
3520 if ((*bp)[0] == L':')
3521 {
3522 /* move over the column to port part */
3523 (*bp)++;
3524 /* next char should be numeric */
3525 if ((*bp)[0] < L'0' || (*bp)[0] > L'9')
3526 {
3527 if (lpErrno) *lpErrno = WSAEINVAL;
3528 return SOCKET_ERROR;
3529 }
3530 port = wcstol(*bp, bp, 10);
3531 }
3532 else
3533 {
3534 port = 0;
3535 }
3536
3537 if (lpErrno) *lpErrno = NO_ERROR;
3538 /* rest sockaddr.sin_addr.s_addr
3539 for we need to be sure it is zero when we come to while */
3540 *lpAddressLength = sizeof(*sockaddr);
3541 memset(lpAddress, 0, sizeof(*sockaddr));
3542 sockaddr->sin_family = AF_INET;
3543 sockaddr->sin_addr.s_addr = inetaddr;
3544 sockaddr->sin_port = port;
3545 }
3546 }
3547
3548 if (lpErrno && !*lpErrno)
3549 {
3550 return 0;
3551 }
3552
3553 return SOCKET_ERROR;
3554}
3555
3556/*
3557 * FUNCTION: Cleans up service provider for a client
3558 * ARGUMENTS:
3559 * lpErrno = Address of buffer for error information
3560 * RETURNS:
3561 * 0 if successful, or SOCKET_ERROR if not
3562 */
3563INT
3564WSPAPI
3566
3567{
3568 TRACE("Leaving.\n");
3569
3570 if (lpErrno) *lpErrno = NO_ERROR;
3571
3572 return 0;
3573}
3574
3575static
3576VOID
3577NTAPI
3582{
3584
3585 TRACE("MsafdInfoAPC(%p %lx %lx)\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information);
3586
3587 if (Context->lpCompletionRoutine)
3588 Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
3589
3590 /* Free IOCTL buffer */
3591 HeapFree(GlobalHeap, 0, Context->lpInfoData);
3592
3594}
3595
3596int
3598 ULONG AfdInformationClass,
3599 PBOOLEAN Boolean OPTIONAL,
3601 PLARGE_INTEGER LargeInteger OPTIONAL,
3602 LPWSAOVERLAPPED Overlapped OPTIONAL,
3604{
3605 PIO_STATUS_BLOCK IOSB;
3606 IO_STATUS_BLOCK DummyIOSB;
3607 PAFD_INFO InfoData;
3609 PMSAFD_INFO_APC_CONTEXT APCContext;
3610 PIO_APC_ROUTINE APCFunction;
3611 HANDLE Event = NULL;
3613
3614 InfoData = HeapAlloc(GlobalHeap, 0, sizeof(*InfoData));
3615 if (!InfoData)
3616 return SOCKET_ERROR;
3617
3620 NULL,
3622 FALSE);
3623 if (!NT_SUCCESS(Status))
3624 {
3625 HeapFree(GlobalHeap, 0, InfoData);
3626 return SOCKET_ERROR;
3627 }
3628
3629 /* Set Info Class */
3630 InfoData->InformationClass = AfdInformationClass;
3631
3632 /* Verify if we should use APC */
3633 if (!Overlapped)
3634 {
3635 /* Not using Overlapped structure, so use normal blocking on event */
3636 APCContext = NULL;
3637 APCFunction = NULL;
3638 Event = SockEvent;
3639 IOSB = &DummyIOSB;
3640 }
3641 else
3642 {
3643 /* Overlapped request for non overlapped opened socket */
3644 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3645 {
3646 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3648 HeapFree(GlobalHeap, 0, InfoData);
3650 }
3651
3652 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
3653 if (!APCContext)
3654 {
3655 ERR("Not enough memory for APC Context\n");
3657 HeapFree(GlobalHeap, 0, InfoData);
3659 }
3661 APCContext->lpOverlapped = Overlapped;
3662 APCContext->lpInfoData = InfoData;
3663 APCFunction = &MsafdInfoAPC;
3664
3665 if (!CompletionRoutine)
3666 Event = Overlapped->hEvent;
3667
3668 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3669 }
3670
3671 IOSB->Status = STATUS_PENDING;
3672
3673 /* Send IOCTL */
3675 Event,
3676 APCFunction,
3677 APCContext,
3678 IOSB,
3680 InfoData,
3681 sizeof(*InfoData),
3682 InfoData,
3683 sizeof(*InfoData));
3684
3685 /* Wait for completion if not overlapped */
3686 if (!Overlapped && Status == STATUS_PENDING)
3687 {
3689 Status = IOSB->Status;
3690 }
3691
3692 TRACE("Status %lx\n", Status);
3693
3694 if (Status == STATUS_SUCCESS)
3695 {
3696 /* Return Information */
3697 if (Ulong != NULL)
3698 {
3699 *Ulong = InfoData->Information.Ulong;
3700 }
3701 if (LargeInteger != NULL)
3702 {
3703 *LargeInteger = InfoData->Information.LargeInteger;
3704 }
3705 if (Boolean != NULL)
3706 {
3707 *Boolean = InfoData->Information.Boolean;
3708 }
3709 }
3710
3712 if (!APCFunction)
3713 {
3714 /* When using APC, this will be freed by the APC function */
3715 HeapFree(GlobalHeap, 0, InfoData);
3716 }
3717
3718 return MsafdReturnWithErrno(Status, NULL, 0, NULL);
3719}
3720
3721
3722int
3724 ULONG AfdInformationClass,
3725 PBOOLEAN Boolean OPTIONAL,
3727 PLARGE_INTEGER LargeInteger OPTIONAL,
3728 LPWSAOVERLAPPED Overlapped OPTIONAL,
3730{
3731 PIO_STATUS_BLOCK IOSB;
3732 IO_STATUS_BLOCK DummyIOSB;
3733 PAFD_INFO InfoData;
3735 PMSAFD_INFO_APC_CONTEXT APCContext;
3736 PIO_APC_ROUTINE APCFunction;
3737 HANDLE Event = NULL;
3739
3740 InfoData = HeapAlloc(GlobalHeap, 0, sizeof(*InfoData));
3741 if (!InfoData)
3742 return SOCKET_ERROR;
3743
3746 NULL,
3748 FALSE);
3749 if (!NT_SUCCESS(Status))
3750 {
3751 HeapFree(GlobalHeap, 0, InfoData);
3752 return SOCKET_ERROR;
3753 }
3754
3755 /* Set Info Class */
3756 InfoData->InformationClass = AfdInformationClass;
3757
3758 /* Set Information */
3759 if (Ulong != NULL)
3760 {
3761 InfoData->Information.Ulong = *Ulong;
3762 }
3763 if (LargeInteger != NULL)
3764 {
3765 InfoData->Information.LargeInteger = *LargeInteger;
3766 }
3767 if (Boolean != NULL)
3768 {
3769 InfoData->Information.Boolean = *Boolean;
3770 }
3771
3772 /* Verify if we should use APC */
3773 if (!Overlapped)
3774 {
3775 /* Not using Overlapped structure, so use normal blocking on event */
3776 APCContext = NULL;
3777 APCFunction = NULL;
3778 Event = SockEvent;
3779 IOSB = &DummyIOSB;
3780 }
3781 else
3782 {
3783 /* Overlapped request for non overlapped opened socket */
3784 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3785 {
3786 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3788 HeapFree(GlobalHeap, 0, InfoData);
3790 }
3791
3792 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
3793 if (!APCContext)
3794 {
3795 ERR("Not enough memory for APC Context\n");
3797 HeapFree(GlobalHeap, 0, InfoData);
3799 }
3801 APCContext->lpOverlapped = Overlapped;
3802 APCContext->lpInfoData = InfoData;
3803 APCFunction = &MsafdInfoAPC;
3804
3805 if (!CompletionRoutine)
3806 Event = Overlapped->hEvent;
3807
3808 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3809 }
3810
3811 IOSB->Status = STATUS_PENDING;
3812
3813 /* Send IOCTL */
3815 Event,
3816 APCFunction,
3817 APCContext,
3818 IOSB,
3820 InfoData,
3821 sizeof(*InfoData),
3822 NULL,
3823 0);
3824
3825 /* Wait for completion if not overlapped */
3826 if (!Overlapped && Status == STATUS_PENDING)
3827 {
3829 Status = IOSB->Status;
3830 }
3831
3832 TRACE("Status %lx\n", Status);
3833
3835 if (!APCFunction)
3836 {
3837 /* When using APC, this will be freed by the APC function */
3838 HeapFree(GlobalHeap, 0, InfoData);
3839 }
3840
3841 return MsafdReturnWithErrno(Status, NULL, 0, NULL);
3842}
3843
3846{
3847 PSOCKET_INFORMATION CurrentSocket;
3848
3850
3851 CurrentSocket = SocketListHead;
3852 while (CurrentSocket)
3853 {
3854 if (CurrentSocket->Handle == Handle)
3855 {
3857 return CurrentSocket;
3858 }
3859
3860 CurrentSocket = CurrentSocket->NextSocket;
3861 }
3862
3864
3865 return NULL;
3866}
3867
3869{
3870 IO_STATUS_BLOCK IOSB;
3871 SOCKET_CONTEXT ContextData;
3874
3877 NULL,
3879 FALSE);
3880
3881 if( !NT_SUCCESS(Status) )
3882 return SOCKET_ERROR;
3883
3884 /* Create Context */
3885 ContextData.SharedData = *Socket->SharedData;
3886 ContextData.SizeOfHelperData = 0;
3887 RtlCopyMemory (&ContextData.LocalAddress,
3888 Socket->LocalAddress,
3890 RtlCopyMemory (&ContextData.RemoteAddress,
3891 Socket->RemoteAddress,
3893
3894 /* Send IOCTL */
3896 SockEvent,
3897 NULL,
3898 NULL,
3899 &IOSB,
3901 &ContextData,
3902 sizeof(ContextData),
3903 NULL,
3904 0);
3905
3906 /* Wait for Completion */
3907 if (Status == STATUS_PENDING)
3908 {
3910 Status = IOSB.Status;
3911 }
3912
3913 NtClose( SockEvent );
3914
3916}
3917
3919{
3920 HANDLE hAsyncThread;
3921 DWORD AsyncThreadId;
3922 HANDLE AsyncEvent;
3925
3926 /* Check if the Thread Already Exists */
3928 {
3930 return TRUE;
3931 }
3932
3933 /* Create the Completion Port */
3935 {
3938 NULL,
3939 2); // Allow 2 threads only
3940 if (!NT_SUCCESS(Status))
3941 {
3942 ERR("Failed to create completion port: 0x%08x\n", Status);
3943 return FALSE;
3944 }
3945 /* Protect Handle */
3946 HandleFlags.ProtectFromClose = TRUE;
3947 HandleFlags.Inherit = FALSE;
3950 &HandleFlags,
3951 sizeof(HandleFlags));
3952 }
3953
3954 /* Create the Async Event */
3955 Status = NtCreateEvent(&AsyncEvent,
3957 NULL,
3959 FALSE);
3960
3961 /* Create the Async Thread */
3962 hAsyncThread = CreateThread(NULL,
3963 0,
3965 NULL,
3966 0,
3967 &AsyncThreadId);
3968
3969 /* Close the Handle */
3970 NtClose(hAsyncThread);
3971
3972 /* Increase the Reference Count */
3974 return TRUE;
3975}
3976
3977ULONG
3978NTAPI
3980{
3981 PVOID AsyncContext;
3982 PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine;
3983 IO_STATUS_BLOCK IOSB;
3985
3986 /* Make the Thread Higher Priority */
3988
3989 /* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */
3990 do
3991 {
3993 (PVOID*)&AsyncCompletionRoutine,
3994 &AsyncContext,
3995 &IOSB,
3996 NULL);
3997 /* Call the Async Function */
3998 if (NT_SUCCESS(Status))
3999 {
4000 (*AsyncCompletionRoutine)(AsyncContext, &IOSB);
4001 }
4002 else
4003 {
4004 /* It Failed, sleep for a second */
4005 Sleep(1000);
4006 }
4007 } while ((Status != STATUS_TIMEOUT));
4008
4009 /* The Thread has Ended */
4010 return 0;
4011}
4012
4014{
4015 UNICODE_STRING AfdHelper;
4017 IO_STATUS_BLOCK IoSb;
4018 FILE_COMPLETION_INFORMATION CompletionInfo;
4020
4021 /* First, make sure we're not already initialized */
4023 {
4024 return TRUE;
4025 }
4026
4027 /* Set up Handle Name and Object */
4028 RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" );
4030 &AfdHelper,
4032 NULL,
4033 NULL);
4034
4035 /* Open the Handle to AFD */
4039 &IoSb,
4040 NULL,
4041 0,
4044 0,
4045 NULL,
4046 0);
4047
4048 /*
4049 * Now Set up the Completion Port Information
4050 * This means that whenever a Poll is finished, the routine will be executed
4051 */
4052 CompletionInfo.Port = SockAsyncCompletionPort;
4053 CompletionInfo.Key = SockAsyncSelectCompletionRoutine;
4055 &IoSb,
4056 &CompletionInfo,
4057 sizeof(CompletionInfo),
4059
4060
4061 /* Protect the Handle */
4062 HandleFlags.ProtectFromClose = TRUE;
4063 HandleFlags.Inherit = FALSE;
4066 &HandleFlags,
4067 sizeof(HandleFlags));
4068
4069
4070 /* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */
4072 return TRUE;
4073}
4074
4076{
4077
4078 PASYNC_DATA AsyncData = Context;
4079 PSOCKET_INFORMATION Socket;
4080 ULONG x;
4081
4082 /* Get the Socket */
4083 Socket = AsyncData->ParentSocket;
4084
4085 /* Check if the Sequence Number Changed behind our back */
4086 if (AsyncData->SequenceNumber != Socket->SharedData->SequenceNumber )
4087 {
4088 return;
4089 }
4090
4091 /* Check we were manually called b/c of a failure */
4093 {
4094 /* FIXME: Perform Upcall */
4095 return;
4096 }
4097
4098 for (x = 1; x; x<<=1)
4099 {
4100 switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x)
4101 {
4102 case AFD_EVENT_RECEIVE:
4103 if (0 != (Socket->SharedData->AsyncEvents & FD_READ) &&
4104 0 == (Socket->SharedData->AsyncDisabledEvents & FD_READ))
4105 {
4106 /* Make the Notification */
4108 Socket->SharedData->wMsg,
4109 Socket->Handle,
4111 /* Disable this event until the next read(); */
4113 }
4114 break;
4115
4117 if (0 != (Socket->SharedData->AsyncEvents & FD_OOB) &&
4118 0 == (Socket->SharedData->AsyncDisabledEvents & FD_OOB))
4119 {
4120 /* Make the Notification */
4122 Socket->SharedData->wMsg,
4123 Socket->Handle,
4125 /* Disable this event until the next read(); */
4127 }
4128 break;
4129
4130 case AFD_EVENT_SEND:
4131 if (0 != (Socket->SharedData->AsyncEvents & FD_WRITE) &&
4132 0 == (Socket->SharedData->AsyncDisabledEvents & FD_WRITE))
4133 {
4134 /* Make the Notification */
4136 Socket->SharedData->wMsg,
4137 Socket->Handle,
4139 /* Disable this event until the next write(); */
4141 }
4142 break;
4143
4144 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
4145 case AFD_EVENT_CONNECT:
4147 if (0 != (Socket->SharedData->AsyncEvents & FD_CONNECT) &&
4148 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CONNECT))
4149 {
4150 /* Make the Notification */
4152 Socket->SharedData->wMsg,
4153 Socket->Handle,
4155 /* Disable this event forever; */
4157 }
4158 break;
4159
4160 case AFD_EVENT_ACCEPT:
4161 if (0 != (Socket->SharedData->AsyncEvents & FD_ACCEPT) &&
4162 0 == (Socket->SharedData->AsyncDisabledEvents & FD_ACCEPT))
4163 {
4164 /* Make the Notification */
4166 Socket->SharedData->wMsg,
4167 Socket->Handle,
4169 /* Disable this event until the next accept(); */
4171 }
4172 break;
4173
4175 case AFD_EVENT_ABORT:
4176 case AFD_EVENT_CLOSE:
4177 if (0 != (Socket->SharedData->AsyncEvents & FD_CLOSE) &&
4178 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CLOSE))
4179 {
4180 /* Make the Notification */
4182 Socket->SharedData->wMsg,
4183 Socket->Handle,
4185 /* Disable this event forever; */
4187 }
4188 break;
4189 /* FIXME: Support QOS */
4190 }
4191 }
4192
4193 /* Check if there are any events left for us to check */
4194 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
4195 {
4196 return;
4197 }
4198
4199 /* Keep Polling */
4200 SockProcessAsyncSelect(Socket, AsyncData);
4201 return;
4202}
4203
4205{
4206
4207 ULONG lNetworkEvents;
4209
4210 /* Set up the Async Data Event Info */
4211 AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF;
4212 AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF;
4213 AsyncData->AsyncSelectInfo.HandleCount = 1;
4214 AsyncData->AsyncSelectInfo.Exclusive = TRUE;
4215 AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle;
4216 AsyncData->AsyncSelectInfo.Handles[0].Events = 0;
4217
4218 /* Remove unwanted events */
4219 lNetworkEvents = Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents);
4220
4221 /* Set Events to wait for */
4222 if (lNetworkEvents & FD_READ)
4223 {
4225 }
4226
4227 if (lNetworkEvents & FD_WRITE)
4228 {
4230 }
4231
4232 if (lNetworkEvents & FD_OOB)
4233 {
4235 }
4236
4237 if (lNetworkEvents & FD_ACCEPT)
4238 {
4240 }
4241
4242 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
4243 if (lNetworkEvents & FD_CONNECT)
4244 {
4246 }
4247
4248 if (lNetworkEvents & FD_CLOSE)
4249 {
4251 }
4252
4253 if (lNetworkEvents & FD_QOS)
4254 {
4256 }
4257
4258 if (lNetworkEvents & FD_GROUP_QOS)
4259 {
4261 }
4262
4263 /* Send IOCTL */
4265 NULL,
4266 NULL,
4267 AsyncData,
4268 &AsyncData->IoStatusBlock,
4270 &AsyncData->AsyncSelectInfo,
4271 sizeof(AsyncData->AsyncSelectInfo),
4272 &AsyncData->AsyncSelectInfo,
4273 sizeof(AsyncData->AsyncSelectInfo));
4274
4275 /* I/O Manager Won't call the completion routine, let's do it manually */
4276 if (NT_SUCCESS(Status))
4277 {
4278 return;
4279 }
4280 else
4281 {
4282 AsyncData->IoStatusBlock.Status = Status;
4283 SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock);
4284 }
4285}
4286
4288{
4289 PASYNC_DATA AsyncData = Context;
4290 BOOL FreeContext = TRUE;
4291 PSOCKET_INFORMATION Socket;
4292
4293 /* Get the Socket */
4294 Socket = AsyncData->ParentSocket;
4295
4296 /* If someone closed it, stop the function */
4297 if (Socket->SharedData->State != SocketClosed)
4298 {
4299 /* Check if the Sequence Number changed by now, in which case quit */
4300 if (AsyncData->SequenceNumber == Socket->SharedData->SequenceNumber)
4301 {
4302 /* Do the actual select, if needed */
4303 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)))
4304 {
4305 SockProcessAsyncSelect(Socket, AsyncData);
4306 FreeContext = FALSE;
4307 }
4308 }
4309 }
4310
4311 /* Free the Context */
4312 if (FreeContext)
4313 {
4314 HeapFree(GetProcessHeap(), 0, AsyncData);
4315 }
4316
4317 return;
4318}
4319
4320VOID
4322 IN ULONG Event)
4323{
4324 PASYNC_DATA AsyncData;
4325
4326 /* Make sure the event is actually disabled */
4327 if (!(Socket->SharedData->AsyncDisabledEvents & Event))
4328 {
4329 return;
4330 }
4331
4332 /* Re-enable it */
4333 Socket->SharedData->AsyncDisabledEvents &= ~Event;
4334
4335 /* Return if no more events are being polled */
4336 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
4337 {
4338 return;
4339 }
4340
4341 /* Wait on new events */
4342 AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(ASYNC_DATA));
4343 if (!AsyncData) return;
4344
4345 /* Create the Asynch Thread if Needed */
4347
4348 /* Increase the sequence number to stop anything else */
4349 Socket->SharedData->SequenceNumber++;
4350
4351 /* Set up the Async Data */
4352 AsyncData->ParentSocket = Socket;
4353 AsyncData->SequenceNumber = Socket->SharedData->SequenceNumber;
4354
4355 /* Begin Async Select by using I/O Completion */
4358 AsyncData,
4359 0,
4360 0);
4361
4362 /* All done */
4363 return;
4364}
4365
4366BOOL
4367WINAPI
4371{
4372
4373 switch (dwReason)
4374 {
4375 case DLL_PROCESS_ATTACH:
4376
4377 TRACE("Loading MSAFD.DLL \n");
4378
4379 /* Don't need thread attach notifications
4380 so disable them to improve performance */
4381 DisableThreadLibraryCalls(hInstDll);
4382
4383 /* List of DLL Helpers */
4385
4386 /* Heap to use when allocating */
4388
4389 /* Initialize the lock that protects our socket list */
4391
4392 TRACE("MSAFD.DLL has been loaded\n");
4393
4394 break;
4395
4396 case DLL_THREAD_ATTACH:
4397 break;
4398
4399 case DLL_THREAD_DETACH:
4400 break;
4401
4402 case DLL_PROCESS_DETACH:
4403
4404 /* Delete the socket list lock */
4406
4407 break;
4408 }
4409
4410 TRACE("DllMain of msafd.dll (leaving)\n");
4411
4412 return TRUE;
4413}
4414
4415/* EOF */
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
LONG NTSTATUS
Definition: precomp.h:26
HANDLE Events[3]
Definition: schedsvc.c:40
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
DWORD dwReason
Definition: misc.cpp:135
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define HandleToUlong(h)
Definition: basetsd.h:73
w ll
Definition: byte_order.h:167
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define NO_ERROR
Definition: dderror.h:5
#define BufferSize
Definition: mmc.h:75
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
Definition: dllmain.c:52
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define DLL_THREAD_DETACH
Definition: compat.h:133
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define UnmapViewOfFile
Definition: compat.h:746
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define HeapFree(x, y, z)
Definition: compat.h:735
#define DLL_THREAD_ATTACH
Definition: compat.h:132
#define MapViewOfFile
Definition: compat.h:745
#define FILE_SHARE_READ
Definition: compat.h:136
#define FAR
Definition: zlib.h:34
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1225
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
#define IS_INTRESOURCE(x)
Definition: loader.c:613
int SockGetTdiName(PINT AddressFamily, PINT SocketType, PINT Protocol, GROUP Group, DWORD Flags, PUNICODE_STRING TransportName, PVOID *HelperDllContext, PHELPER_DATA *HelperDllData, PDWORD Events)
Definition: helpers.c:22
static VOID NTAPI MsafdInfoAPC(_In_ PVOID ApcContext, _In_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG Reserved)
Definition: dllmain.c:3578
INT WSPAPI WSPAddressToString(IN LPSOCKADDR lpsaAddress, IN DWORD dwAddressLength, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPWSTR lpszAddressString, IN OUT LPDWORD lpdwAddressStringLength, OUT LPINT lpErrno)
Definition: dllmain.c:3381
int WSPAPI WSPListen(SOCKET Handle, int Backlog, LPINT lpErrno)
Definition: dllmain.c:998
INT WSPAPI WSPSetSockOpt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen, OUT LPINT lpErrno)
Definition: dllmain.c:3100
BOOL WSPAPI WSPConnectEx(_In_ SOCKET Handle, _In_ const struct sockaddr *SocketAddress, _In_ int SocketAddressLength, _In_ PVOID lpSendBuffer, _In_ DWORD dwSendDataLength, _Out_ LPDWORD lpdwBytesSent, _Inout_ LPOVERLAPPED lpOverlapped)
Definition: dllmain.c:2182
VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:4075
INT WSPAPI WSPCleanup(OUT LPINT lpErrno)
Definition: dllmain.c:3565
int GetSocketInformation(PSOCKET_INFORMATION Socket, ULONG AfdInformationClass, PBOOLEAN Boolean OPTIONAL, PULONG Ulong OPTIONAL, PLARGE_INTEGER LargeInteger OPTIONAL, LPWSAOVERLAPPED Overlapped OPTIONAL, LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL)
Definition: dllmain.c:3597
int WSPAPI WSPConnect(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
Definition: dllmain.c:1901
INT WSPAPI WSPGetSockOpt(IN SOCKET Handle, IN INT Level, IN INT OptionName, OUT CHAR FAR *OptionValue, IN OUT LPINT OptionLength, OUT LPINT lpErrno)
Definition: dllmain.c:2814
HANDLE SockAsyncCompletionPort
Definition: dllmain.c:28
INT WSPAPI WSPBind(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPINT lpErrno)
Definition: dllmain.c:860
BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
Definition: dllmain.c:3918
VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
Definition: dllmain.c:4204
DWORD CatalogEntryId
Definition: dllmain.c:21
LIST_ENTRY SockHelpersListHead
Definition: dllmain.c:25
HANDLE SockAsyncHelperAfdHandle
Definition: dllmain.c:27
VOID MsafdWaitForAlert(_In_ HANDLE hObject)
Definition: dllmain.c:614
DWORD GetCurrentTimeInSeconds(VOID)
Definition: dllmain.c:1434
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3845
INT WSPAPI WSPGetPeerName(IN SOCKET s, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
Definition: dllmain.c:2463
HANDLE GlobalHeap
Definition: dllmain.c:19
int WSPAPI WSPSelect(IN int nfds, IN OUT fd_set *readfds OPTIONAL, IN OUT fd_set *writefds OPTIONAL, IN OUT fd_set *exceptfds OPTIONAL, IN const struct timeval *timeout OPTIONAL, OUT LPINT lpErrno)
Definition: dllmain.c:1082
int CreateContext(PSOCKET_INFORMATION Socket)
Definition: dllmain.c:3868
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:4287
int SetSocketInformation(PSOCKET_INFORMATION Socket, ULONG AfdInformationClass, PBOOLEAN Boolean OPTIONAL, PULONG Ulong OPTIONAL, PLARGE_INTEGER LargeInteger OPTIONAL, LPWSAOVERLAPPED Overlapped OPTIONAL, LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL)
Definition: dllmain.c:3723
INT WSPAPI WSPDuplicateSocket(IN SOCKET Handle, IN DWORD dwProcessId, OUT LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPINT lpErrno)
Definition: dllmain.c:449
ULONG NTAPI SockAsyncThread(PVOID ThreadParam)
Definition: dllmain.c:3979
int WSPAPI WSPShutdown(SOCKET Handle, int HowTo, LPINT lpErrno)
Definition: dllmain.c:2281
INT WSPAPI WSPStringToAddress(IN LPWSTR AddressString, IN INT AddressFamily, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPSOCKADDR lpAddress, IN OUT LPINT lpAddressLength, OUT LPINT lpErrno)
Definition: dllmain.c:3441
_Must_inspect_result_ int WSPAPI WSPStartup(_In_ WORD wVersionRequested, _In_ LPWSPDATA lpWSPData, _In_ LPWSAPROTOCOL_INFOW lpProtocolInfo, _In_ WSPUPCALLTABLE UpcallTable, _Out_ LPWSPPROC_TABLE lpProcTable)
Definition: dllmain.c:3316
INT WSPAPI WSPIoctl(IN SOCKET Handle, IN DWORD dwIoControlCode, IN LPVOID lpvInBuffer, IN DWORD cbInBuffer, OUT LPVOID lpvOutBuffer, IN DWORD cbOutBuffer, OUT LPDWORD lpcbBytesReturned, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, IN LPWSATHREADID lpThreadId, OUT LPINT lpErrno)
Definition: dllmain.c:2566
ULONG SockAsyncThreadRefCount
Definition: dllmain.c:26
INT WSPAPI WSPCloseSocket(IN SOCKET Handle, OUT LPINT lpErrno)
Definition: dllmain.c:637
INT TranslateNtStatusError(NTSTATUS Status)
Definition: dllmain.c:537
_Must_inspect_result_ SOCKET WSPAPI WSPAccept(_In_ SOCKET Handle, _Out_writes_bytes_to_opt_(*addrlen, *addrlen) struct sockaddr FAR *SocketAddress, _Inout_opt_ LPINT SocketAddressLength, _In_opt_ LPCONDITIONPROC lpfnCondition, _In_opt_ DWORD_PTR dwCallbackData, _Out_ LPINT lpErrno)
Definition: dllmain.c:1451
SOCKET WSPAPI WSPSocket(int AddressFamily, int SocketType, int Protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)
Definition: dllmain.c:48
static VOID NTAPI MsafdConnectAPC(_In_ PVOID ApcContext, _In_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG Reserved)
Definition: dllmain.c:1848
static INT NTAPI MsafdUpdateConnectionContext(_In_ SOCKET Handle, _Out_ LPINT lpErrno)
Definition: dllmain.c:2991
INT WSPAPI WSPGetSockName(IN SOCKET Handle, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
Definition: dllmain.c:2361
BOOLEAN SockAsyncSelectCalled
Definition: dllmain.c:29
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:4321
WSPUPCALLTABLE Upcalls
Definition: dllmain.c:20
BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID)
Definition: dllmain.c:4013
PSOCKET_INFORMATION SocketListHead
Definition: dllmain.c:23
CRITICAL_SECTION SocketListLock
Definition: dllmain.c:24
LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest
Definition: dllmain.c:22
INT WSPAPI WSPEnumNetworkEvents(IN SOCKET Handle, IN WSAEVENT hEventObject, OUT LPWSANETWORKEVENTS lpNetworkEvents, OUT LPINT lpErrno)
Definition: event.c:133
int WSPAPI WSPEventSelect(IN SOCKET Handle, IN WSAEVENT hEventObject, IN long lNetworkEvents, OUT LPINT lpErrno)
Definition: event.c:17
INT WSPAPI WSPCancelBlockingCall(OUT LPINT lpErrno)
Definition: stubs.c:15
BOOL WSPAPI WSPAcceptEx(IN SOCKET sListenSocket, IN SOCKET sAcceptSocket, OUT PVOID lpOutputBuffer, IN DWORD dwReceiveDataLength, IN DWORD dwLocalAddressLength, IN DWORD dwRemoteAddressLength, OUT LPDWORD lpdwBytesReceived, IN OUT LPOVERLAPPED lpOverlapped)
Definition: stubs.c:58
VOID WSPAPI WSPGetAcceptExSockaddrs(IN PVOID lpOutputBuffer, IN DWORD dwReceiveDataLength, IN DWORD dwLocalAddressLength, IN DWORD dwRemoteAddressLength, OUT struct sockaddr **LocalSockaddr, OUT LPINT LocalSockaddrLength, OUT struct sockaddr **RemoteSockaddr, OUT LPINT RemoteSockaddrLength)
Definition: stubs.c:88
BOOL WSPAPI WSPDisconnectEx(IN SOCKET hSocket, IN LPOVERLAPPED lpOverlapped, IN DWORD dwFlags, IN DWORD reserved)
Definition: stubs.c:75
SOCKET WSPAPI WSPJoinLeaf(IN SOCKET s, IN CONST SOCKADDR *name, IN INT namelen, IN LPWSABUF lpCallerData, OUT LPWSABUF lpCalleeData, IN LPQOS lpSQOS, IN LPQOS lpGQOS, IN DWORD dwFlags, OUT LPINT lpErrno)
Definition: stubs.c:40
BOOL WSPAPI WSPGetQOSByName(IN SOCKET s, IN OUT LPWSABUF lpQOSName, OUT LPQOS lpQOS, OUT LPINT lpErrno)
Definition: stubs.c:26
FORCEINLINE DWORD MsafdReturnWithErrno(_In_ NTSTATUS Status, _Out_opt_ LPINT Errno, _In_ DWORD Received, _Out_opt_ LPDWORD ReturnedBytes)
Definition: msafd.h:515
HANDLE SockEvent
VOID(* PASYNC_COMPLETION_ROUTINE)(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: msafd.h:511
_ACRTIMP __msvcrt_long __cdecl wcstol(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2747
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
USHORT port
Definition: uri.c:228
#define swprintf
Definition: precomp.h:40
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
#define L(x)
Definition: resources.c:13
#define IPPROTO_RAW
Definition: ip.h:192
#define IPPROTO_TCP
Definition: ip.h:196
#define IPPROTO_UDP
Definition: ip.h:197
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
#define INFINITE
Definition: serial.h:102
#define UlongToPtr(u)
Definition: config.h:106
#define PAGE_SIZE
Definition: env_spec_w32.h:49
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_VIOLATION
@ FileCompletionInformation
Definition: from_kernel.h:91
#define FILE_OPEN_IF
Definition: from_kernel.h:56
struct _FILE_FULL_EA_INFORMATION FILE_FULL_EA_INFORMATION
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLint level
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLdouble s
Definition: gl.h:2039
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG)
Definition: largeint.c:31
@ ObjectHandleFlagInformation
Definition: winternl.h:1876
NTSYSAPI LONGLONG WINAPI RtlEnlargedIntegerMultiply(INT, INT)
#define PROCESS_DUP_HANDLE
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
Definition: iocomp.c:569
NTSTATUS NTAPI NtRemoveIoCompletion(IN HANDLE IoCompletionHandle, OUT PVOID *KeyContext, OUT PVOID *ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: iocomp.c:445
NTSTATUS NTAPI NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG NumberOfConcurrentThreads)
Definition: iocomp.c:253
BOOL WINAPI PostQueuedCompletionStatus(IN HANDLE CompletionHandle, IN DWORD dwNumberOfBytesTransferred, IN ULONG_PTR dwCompletionKey, IN LPOVERLAPPED lpOverlapped)
Definition: iocompl.c:192
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
if(dx< 0)
Definition: linetemp.h:194
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
int * LPINT
Definition: minwindef.h:151
#define error(str)
Definition: mkdosfs.c:1605
#define ASSERT(a)
Definition: mode.c:44
#define ntohl(x)
Definition: module.h:205
#define ntohs(x)
Definition: module.h:210
#define IO_COMPLETION_ALL_ACCESS
Definition: file.c:72
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static PLARGE_INTEGER Time
Definition: time.c:105
#define WSAID_GETACCEPTEXSOCKADDRS
Definition: mswsock.h:77
#define SO_CONNECT_TIME
Definition: mswsock.h:36
#define WSAID_ACCEPTEX
Definition: mswsock.h:74
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:93
IN PCO_ADDRESS_FAMILY AddressFamily
Definition: ndis.h:1906
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:727
#define SEC_COMMIT
Definition: mmtypes.h:100
#define AFD_SHARE_WILDCARD
Definition: netio.c:69
#define AFD_SHARE_UNIQUE
Definition: netio.c:67
#define AFD_SHARE_EXCLUSIVE
Definition: netio.c:70
#define AFD_SHARE_REUSE
Definition: netio.c:68
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _Inout_
Definition: no_sal2.h:162
#define _Inout_opt_
Definition: no_sal2.h:216
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Out_writes_bytes_to_opt_(s, c)
Definition: no_sal2.h:240
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define PAGE_READWRITE
Definition: nt_native.h:1307
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
#define GENERIC_WRITE
Definition: nt_native.h:90
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:880
@ NotificationEvent
@ SynchronizationEvent
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:651
#define STATUS_NETWORK_UNREACHABLE
Definition: ntstatus.h:826
#define STATUS_CANT_WAIT
Definition: ntstatus.h:546
#define STATUS_ADDRESS_ALREADY_EXISTS
Definition: ntstatus.h:776
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:626
#define STATUS_HOST_UNREACHABLE
Definition: ntstatus.h:827
#define STATUS_REMOTE_DISCONNECT
Definition: ntstatus.h:646
#define STATUS_INVALID_CONNECTION
Definition: ntstatus.h:650
#define STATUS_REMOTE_NOT_LISTENING
Definition: ntstatus.h:518
#define STATUS_LOCAL_DISCONNECT
Definition: ntstatus.h:645
#define STATUS_PROTOCOL_NOT_SUPPORTED
Definition: ntstatus.h:1410
NTSTATUS NTAPI NtSetInformationObject(IN HANDLE ObjectHandle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, IN PVOID ObjectInformation, IN ULONG Length)
Definition: oblife.c:1824
#define CONST
Definition: pedump.c:81
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
static ULONG Timeout
Definition: ping.c:61
#define INT
Definition: polytest.cpp:20
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
_In_ DWORD dwProcessId
Definition: shlwapi.h:193
#define AFD_INFO_SEND_WINDOW_SIZE
Definition: shared.h:192
#define IOCTL_AFD_GET_TDI_HANDLES
Definition: shared.h:300
#define AFD_EVENT_ACCEPT
Definition: shared.h:216
#define AFD_INFO_RECEIVE_WINDOW_SIZE
Definition: shared.h:191
struct _AFD_POLL_INFO * PAFD_POLL_INFO
#define AFD_DISCONNECT_RECV
Definition: shared.h:204
struct _AFD_CREATE_PACKET * PAFD_CREATE_PACKET
#define IOCTL_AFD_SET_INFO
Definition: shared.h:302
struct _AFD_CONNECT_INFO * PAFD_CONNECT_INFO
#define AFD_EVENT_SEND
Definition: shared.h:211
#define AfdCommand
Definition: shared.h:12
#define AFD_INFO_RECEIVE_CONTENT_SIZE
Definition: shared.h:194
#define IOCTL_AFD_WAIT_FOR_LISTEN
Definition: shared.h:280
#define AFD_PACKET_COMMAND_LENGTH
Definition: shared.h:11
#define IOCTL_AFD_GET_SOCK_NAME
Definition: shared.h:296
#define IOCTL_AFD_DEFER_ACCEPT
Definition: shared.h:338
#define IOCTL_AFD_START_LISTEN
Definition: shared.h:278
#define AFD_EVENT_OOB_RECEIVE
Definition: shared.h:210
#define AFD_EVENT_CONNECT_FAIL
Definition: shared.h:217
#define AFD_EVENT_RECEIVE
Definition: shared.h:209
struct _AFD_RECEIVED_ACCEPT_DATA * PAFD_RECEIVED_ACCEPT_DATA
#define AFD_ENDPOINT_RAW
Definition: shared.h:161
#define IOCTL_AFD_GET_CONTEXT
Definition: shared.h:306
struct _AFD_HANDLE_ AFD_HANDLE
#define IOCTL_AFD_SELECT
Definition: shared.h:292
#define AFD_DISCONNECT_ABORT
Definition: shared.h:205
#define AFD_EVENT_DISCONNECT
Definition: shared.h:212
#define AFD_ENDPOINT_D_ROOT
Definition: shared.h:164
#define AFD_INFO_BLOCKING_MODE
Definition: shared.h:189
#define AFD_ENDPOINT_MULTIPOINT
Definition: shared.h:162
#define IOCTL_AFD_GET_INFO
Definition: shared.h:334
#define IOCTL_AFD_SET_CONNECT_DATA
Definition: shared.h:310
#define AFD_CONNECTION_HANDLE
Definition: shared.h:168
#define IOCTL_AFD_CONNECT
Definition: shared.h:276
struct _AFD_SUPER_CONNECT_INFO * PAFD_SUPER_CONNECT_INFO
#define IOCTL_AFD_ACCEPT
Definition: shared.h:282
#define IOCTL_AFD_BIND
Definition: shared.h:274
#define IOCTL_AFD_DISCONNECT
Definition: shared.h:294
#define AFD_ENDPOINT_MESSAGE_ORIENTED
Definition: shared.h:160
struct _AFD_CREATE_PACKET AFD_CREATE_PACKET
#define AFD_EVENT_ABORT
Definition: shared.h:213
#define AFD_ADDRESS_HANDLE
Definition: shared.h:167
#define AFD_INFO_SENDS_IN_PROGRESS
Definition: shared.h:190
#define IOCTL_AFD_SUPER_CONNECT
Definition: shared.h:346
#define AFD_EVENT_QOS
Definition: shared.h:218
#define AFD_ENDPOINT_CONNECTIONLESS
Definition: shared.h:159
#define IOCTL_AFD_GET_PENDING_CONNECT_DATA
Definition: shared.h:340
#define AFD_EVENT_CLOSE
Definition: shared.h:214
@ SocketBound
Definition: shared.h:363
@ SocketConnected
Definition: shared.h:365
@ SocketClosed
Definition: shared.h:366
@ SocketOpen
Definition: shared.h:362
#define AFD_EVENT_CONNECT
Definition: shared.h:215
#define AFD_EVENT_GROUP_QOS
Definition: shared.h:219
#define IOCTL_AFD_SET_CONNECT_DATA_SIZE
Definition: shared.h:326
#define IOCTL_AFD_GET_PEER_NAME
Definition: shared.h:298
#define IOCTL_AFD_SET_CONTEXT
Definition: shared.h:308
#define AFD_ENDPOINT_C_ROOT
Definition: shared.h:163
#define AFD_INFO_GROUP_ID_TYPE
Definition: shared.h:193
#define IOCTL_AFD_GET_CONNECT_DATA
Definition: shared.h:318
#define AFD_DISCONNECT_SEND
Definition: shared.h:203
wcscpy
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
INT WSPAPI WSPSendDisconnect(IN SOCKET s, IN LPWSABUF lpOutboundDisconnectData, OUT LPINT lpErrno)
Definition: sndrcv.c:1064
int WSPAPI WSPRecvFrom(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRead, LPDWORD ReceiveFlags, struct sockaddr *SocketAddress, int *SocketAddressLength, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:430
BOOL WSPAPI WSPGetOverlappedResult(IN SOCKET Handle, IN LPWSAOVERLAPPED lpOverlapped, OUT LPDWORD lpdwBytes, IN BOOL fWait, OUT LPDWORD lpdwFlags, OUT LPINT lpErrno)
Definition: sndrcv.c:96
INT WSPAPI WSPAsyncSelect(IN SOCKET Handle, IN HWND hWnd, IN UINT wMsg, IN LONG lEvent, OUT LPINT lpErrno)
Definition: sndrcv.c:17
int WSPAPI WSPSendTo(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD iFlags, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:843
int WSPAPI WSPSend(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD iFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:668
int WSPAPI WSPRecv(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRead, LPDWORD ReceiveFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:221
INT WSPAPI WSPRecvDisconnect(IN SOCKET s, OUT LPWSABUF lpInboundDisconnectData, OUT LPINT lpErrno)
Definition: sndrcv.c:1052
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: ws2spi.h:46
HANDLE ListenHandle
Definition: shared.h:65
ULONG SequenceNumber
Definition: shared.h:64
ULONG ShareType
Definition: shared.h:39
TRANSPORT_ADDRESS Address
Definition: shared.h:40
TRANSPORT_ADDRESS RemoteAddress
Definition: shared.h:121
BOOLEAN UseSAN
Definition: shared.h:118
DWORD EndpointFlags
Definition: shared.h:22
WCHAR TransportName[1]
Definition: shared.h:25
DWORD SizeOfTransportName
Definition: shared.h:24
BOOLEAN RejectConnection
Definition: shared.h:81
LARGE_INTEGER Timeout
Definition: shared.h:143
ULONG DisconnectType
Definition: shared.h:142
SOCKET Handle
Definition: shared.h:50
ULONG Events
Definition: shared.h:51
ULONG InformationClass
Definition: shared.h:29
ULONG Ulong
Definition: shared.h:31
union _AFD_INFO::@3563 Information
BOOLEAN Boolean
Definition: shared.h:33
LARGE_INTEGER LargeInteger
Definition: shared.h:32
BOOLEAN UseSAN
Definition: shared.h:44
BOOLEAN UseDelayedAcceptance
Definition: shared.h:46
ULONG Backlog
Definition: shared.h:45
LARGE_INTEGER Timeout
Definition: shared.h:56
ULONG HandleCount
Definition: shared.h:57
AFD_HANDLE Handles[1]
Definition: shared.h:59
ULONG_PTR Exclusive
Definition: shared.h:58
TRANSPORT_ADDRESS Address
Definition: shared.h:70
TRANSPORT_ADDRESS RemoteAddress
Definition: shared.h:127
HANDLE TdiConnectionHandle
Definition: shared.h:155
HANDLE TdiAddressHandle
Definition: shared.h:154
AFD_POLL_INFO AsyncSelectInfo
Definition: msafd.h:80
DWORD SequenceNumber
Definition: msafd.h:78
PSOCKET_INFORMATION ParentSocket
Definition: msafd.h:77
IO_STATUS_BLOCK IoStatusBlock
Definition: msafd.h:79
BOOLEAN UseDelayedAcceptance
Definition: helpers.h:20
PWSH_GET_SOCKADDR_TYPE WSHGetSockaddrType
Definition: helpers.h:28
PWSH_GET_SOCKET_INFORMATION WSHGetSocketInformation
Definition: helpers.h:26
PWSH_IOCTL WSHIoctl
Definition: helpers.h:33
PWSH_SET_SOCKET_INFORMATION WSHSetSocketInformation
Definition: helpers.h:27
PWSH_NOTIFY WSHNotify
Definition: helpers.h:25
INT MaxWSAddressLength
Definition: helpers.h:17
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr
Definition: helpers.h:29
Definition: typedefs.h:120
IO_STATUS_BLOCK IoStatusBlock
Definition: msafd.h:108
PAFD_INFO lpInfoData
Definition: msafd.h:87
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
Definition: msafd.h:86
LPWSAOVERLAPPED lpOverlapped
Definition: msafd.h:85
SOCKADDR_ADDRESS_INFO AddressInfo
Definition: wsahelp.h:44
SOCKADDR_ENDPOINT_INFO EndpointInfo
Definition: wsahelp.h:45
SOCK_SHARED_INFO SharedData
Definition: msafd.h:68
SOCKADDR RemoteAddress
Definition: msafd.h:72
SOCKADDR LocalAddress
Definition: msafd.h:71
ULONG SizeOfHelperData
Definition: msafd.h:69
PVOID HelperContext
Definition: msafd.h:51
LONG NetworkEvents
Definition: msafd.h:58
HANDLE TdiConnectionHandle
Definition: msafd.h:55
struct _SOCKET_INFORMATION * NextSocket
Definition: msafd.h:63
HANDLE SharedDataHandle
Definition: msafd.h:48
PSOCKADDR LocalAddress
Definition: msafd.h:52
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:47
PHELPER_DATA HelperData
Definition: msafd.h:50
PSOCKADDR RemoteAddress
Definition: msafd.h:53
SOCKET Handle
Definition: msafd.h:46
HANDLE TdiAddressHandle
Definition: msafd.h:54
DWORD HelperEvents
Definition: msafd.h:49
WSAPROTOCOL_INFOW ProtocolInfo
Definition: msafd.h:62
DWORD GroupType
Definition: shared.h:401
BOOLEAN Broadcast
Definition: shared.h:385
BOOLEAN Debug
Definition: shared.h:386
LONG AsyncDisabledEvents
Definition: shared.h:409
INT SizeOfLocalAddress
Definition: shared.h:375
ULONG RecvTimeout
Definition: shared.h:379
BOOLEAN ExclusiveAddressUse
Definition: shared.h:389
SOCKADDR WSRemoteAddress
Definition: shared.h:411
BOOLEAN OobInline
Definition: shared.h:387
SOCKET_STATE State
Definition: shared.h:370
ULONG SizeOfSendBuffer
Definition: shared.h:381
BOOLEAN NonBlocking
Definition: shared.h:390
BOOLEAN UseSAN
Definition: shared.h:395
BOOLEAN SendShutdown
Definition: shared.h:393
SOCKADDR WSLocalAddress
Definition: shared.h:410
BOOLEAN ReuseAddresses
Definition: shared.h:388
LONG AsyncEvents
Definition: shared.h:408
ULONG SizeOfRecvBuffer
Definition: shared.h:380
INT SocketLastError
Definition: shared.h:403
struct linger LingerData
Definition: shared.h:377
DWORD SequenceNumber
Definition: shared.h:406
DWORD ProviderFlags
Definition: shared.h:399
INT SizeOfRemoteAddress
Definition: shared.h:376
BOOLEAN ReceiveShutdown
Definition: shared.h:392
ULONG SendTimeout
Definition: shared.h:378
BOOLEAN Listening
Definition: shared.h:384
BOOLEAN UseDelayedAcceptance
Definition: shared.h:394
DWORD ServiceFlags1
Definition: shared.h:398
ULONG ConnectTime
Definition: shared.h:382
DWORD CreateFlags
Definition: shared.h:397
UCHAR Address[1]
Definition: tdi.h:340
USHORT AddressLength
Definition: tdi.h:338
USHORT AddressType
Definition: tdi.h:339
TRANSPORT_ADDRESS Address
Definition: tdi.h:388
TA_ADDRESS Address[1]
Definition: tdi.h:377
LONG TAAddressCount
Definition: tdi.h:376
ULONG len
Definition: ws2def.h:519
CHAR FAR * buf
Definition: ws2def.h:520
DWORD dwServiceFlags3
Definition: winsock2.h:676
DWORD dwCatalogEntryId
Definition: winsock2.h:680
DWORD dwServiceFlags4
Definition: winsock2.h:677
DWORD dwServiceFlags1
Definition: winsock2.h:674
DWORD dwProviderFlags
Definition: winsock2.h:678
LPWPUMODIFYIFSHANDLE lpWPUModifyIFSHandle
Definition: ws2spi.h:608
LPWPUPOSTMESSAGE lpWPUPostMessage
Definition: ws2spi.h:609
Definition: winsock.h:60
u_int fd_count
Definition: winsock.h:61
SOCKET fd_array[FD_SETSIZE]
Definition: winsock.h:62
u_short sa_family
Definition: winsock.h:211
char sa_data[14]
Definition: winsock.h:212
Definition: dhcpd.h:248
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:738
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:687
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
struct _TRANSPORT_ADDRESS TRANSPORT_ADDRESS
#define STATUS_PENDING
Definition: telnetd.h:14
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
static ULONG HandleCount
Definition: uefidisk.c:118
ULONG LowPart
Definition: typedefs.h:106
unsigned long Ulong
Definition: utypes.h:42
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CreateFileMapping
Definition: winbase.h:3499
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1146
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define WAIT_IO_COMPLETION
Definition: winbase.h:388
#define FILE_MAP_ALL_ACCESS
Definition: winbase.h:158
#define THREAD_PRIORITY_ABOVE_NORMAL
Definition: winbase.h:299
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
_In_ DWORD dwIoControlCode
Definition: winddi.h:1700
#define WINAPI
Definition: msvc.h:6
#define WSAEADDRNOTAVAIL
Definition: winerror.h:2865
#define WSAEOPNOTSUPP
Definition: winerror.h:2861
#define WSAEHOSTUNREACH
Definition: winerror.h:2881
#define WSAEWOULDBLOCK
Definition: winerror.h:2851
#define WSAEINVAL
Definition: winerror.h:2845
#define WSAENOTSOCK
Definition: winerror.h:2854
#define WSAECONNABORTED
Definition: winerror.h:2869
#define WSAENETDOWN
Definition: winerror.h:2866
#define WSAENOBUFS
Definition: winerror.h:2871
#define WSAETIMEDOUT
Definition: winerror.h:2876
#define WSAEMSGSIZE
Definition: winerror.h:2856
#define WSAECONNRESET
Definition: winerror.h:2870
#define WSAEACCES
Definition: winerror.h:2843
#define WSAVERNOTSUPPORTED
Definition: winerror.h:2893
#define WSAESHUTDOWN
Definition: winerror.h:2874
#define WSAENOPROTOOPT
Definition: winerror.h:2858
#define WSAENETUNREACH
Definition: winerror.h:2867
#define WSAEAFNOSUPPORT
Definition: winerror.h:2863
#define WSAECONNREFUSED
Definition: winerror.h:2877
#define WSAENOTCONN
Definition: winerror.h:2873
#define WSAEADDRINUSE
Definition: winerror.h:2864
#define WSAEFAULT
Definition: winerror.h:2844
unsigned int GROUP
Definition: winsock2.h:634
#define WSA_FLAG_MULTIPOINT_D_LEAF
Definition: winsock2.h:464
#define XP1_MULTIPOINT_DATA_PLANE
Definition: winsock2.h:442
#define FD_QOS
Definition: winsock2.h:300
#define FD_GROUP_QOS
Definition: winsock2.h:302
#define XP1_CONNECTIONLESS
Definition: winsock2.h:430
#define CF_REJECT
Definition: winsock2.h:408
#define WSA_FLAG_MULTIPOINT_C_ROOT
Definition: winsock2.h:461
#define WSA_OPERATION_ABORTED
Definition: winsock2.h:615
#define XP1_SUPPORT_MULTIPOINT
Definition: winsock2.h:440
#define XP1_QOS_SUPPORTED
Definition: winsock2.h:443
#define XP1_PSEUDO_STREAM
Definition: winsock2.h:434
#define WSA_IO_PENDING
Definition: winsock2.h:610
#define XP1_MULTIPOINT_CONTROL_PLANE
Definition: winsock2.h:441
void(CALLBACK * LPWSAOVERLAPPED_COMPLETION_ROUTINE)(IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, IN DWORD dwFlags)
Definition: winsock2.h:716
#define CF_ACCEPT
Definition: winsock2.h:407
#define XP1_MESSAGE_ORIENTED
Definition: winsock2.h:433
#define XP1_CONNECT_DATA
Definition: winsock2.h:437
#define WSA_FLAG_MULTIPOINT_D_ROOT
Definition: winsock2.h:463
#define SO_PROTOCOL_INFOW
Definition: winsock2.h:243
#define WSA_FLAG_MULTIPOINT_C_LEAF
Definition: winsock2.h:462
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:705
#define SO_ERROR
Definition: winsock.h:188
#define SO_KEEPALIVE
Definition: winsock.h:175
#define SD_BOTH
Definition: winsock.h:50
#define SIOCATMARK
Definition: winsock.h:247
#define SO_RCVBUF
Definition: winsock.h:183
#define FD_READ
Definition: winsock.h:399
#define FD_ZERO(set)
Definition: winsock.h:90
#define FD_WRITE
Definition: winsock.h:400
#define SO_OOBINLINE
Definition: winsock.h:180
#define INVALID_SOCKET
Definition: winsock.h:326
struct sockaddr_in SOCKADDR_IN
Definition: winsock.h:481
#define SOCK_RAW
Definition: winsock.h:331
#define FD_CLOSE
Definition: winsock.h:404
#define SO_DONTROUTE
Definition: winsock.h:176
#define SO_ACCEPTCONN
Definition: winsock.h:173
#define SOCK_DGRAM
Definition: winsock.h:330
UINT_PTR SOCKET
Definition: winsock.h:41
#define SO_LINGER
Definition: winsock.h:179
#define SO_REUSEADDR
Definition: winsock.h:174
#define SOCKET_ERROR
Definition: winsock.h:327
#define SO_TYPE
Definition: winsock.h:189
#define SOL_SOCKET
Definition: winsock.h:392
#define SO_DEBUG
Definition: winsock.h:172
#define SD_SEND
Definition: winsock.h:49
#define SO_SNDTIMEO
Definition: winsock.h:186
#define FD_CONNECT
Definition: winsock.h:403
#define FIONREAD
Definition: winsock.h:241
#define FD_SET(fd, set)
Definition: winsock.h:83
#define WSAMAKESELECTREPLY(e, error)
Definition: winsock.h:472
#define SO_BROADCAST
Definition: winsock.h:177
#define FD_OOB
Definition: winsock.h:401
#define SD_RECEIVE
Definition: winsock.h:48
#define AF_UNSPEC
Definition: winsock.h:338
#define SO_DONTLINGER
Definition: winsock.h:181
#define SO_RCVTIMEO
Definition: winsock.h:187
#define FIONBIO
Definition: winsock.h:143
#define SO_SNDBUF
Definition: winsock.h:182
#define FD_ACCEPT
Definition: winsock.h:402
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
#define SO_CONDITIONAL_ACCEPT
Definition: ws2def.h:121
#define SO_EXCLUSIVEADDRUSE
Definition: ws2def.h:105
#define SIO_ADDRESS_LIST_QUERY
Definition: ws2def.h:177
#define SO_GROUP_ID
Definition: ws2def.h:117
struct _SOCKET_ADDRESS_LIST SOCKET_ADDRESS_LIST
#define SO_MAX_MSG_SIZE
Definition: ws2def.h:119
#define SO_GROUP_PRIORITY
Definition: ws2def.h:118
#define SIO_GET_EXTENSION_FUNCTION_POINTER
Definition: ws2def.h:167
#define WSPAPI
Definition: ws2spi.h:39
int(WSPAPI * LPWPUCOMPLETEOVERLAPPEDREQUEST)(_In_ SOCKET s, _Inout_ LPWSAOVERLAPPED lpOverlapped, _In_ DWORD dwError, _In_ DWORD cbTransferred, _Out_ LPINT lpErrno)
Definition: ws2spi.h:408
#define WSH_NOTIFY_LISTEN
Definition: wsahelp.h:11
#define WSH_NOTIFY_CLOSE
Definition: wsahelp.h:17
@ SockaddrEndpointInfoWildcard
Definition: wsahelp.h:31
@ SockaddrAddressInfoBroadcast
Definition: wsahelp.h:26
#define WSH_NOTIFY_CONNECT_ERROR
Definition: wsahelp.h:18
#define WSH_NOTIFY_ACCEPT
Definition: wsahelp.h:13
#define WSH_NOTIFY_CONNECT
Definition: wsahelp.h:12
#define WSH_NOTIFY_BIND
Definition: wsahelp.h:10
enum _SOCKET_STATE SOCKET_STATE
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _In_opt_ PWSK_SOCKET AcceptSocket
Definition: wsk.h:173
_In_ USHORT SocketType
Definition: wsk.h:182
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR RemoteAddress
Definition: wsk.h:172
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define DUPLICATE_SAME_ACCESS
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175