ReactOS 0.4.16-dev-2206-gc56950d
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
872 /* Get the Socket Structure associate to this Socket*/
873 Socket = GetSocketStructure(Handle);
874 if (!Socket)
875 {
876 if (lpErrno) *lpErrno = WSAENOTSOCK;
877 return SOCKET_ERROR;
878 }
879 if (Socket->SharedData->State != SocketOpen)
880 {
881 if (lpErrno) *lpErrno = WSAEINVAL;
882 return SOCKET_ERROR;
883 }
884 if (!SocketAddress || SocketAddressLength < Socket->SharedData->SizeOfLocalAddress)
885 {
886 if (lpErrno) *lpErrno = WSAEINVAL;
887 return SOCKET_ERROR;
888 }
889
890 /* Get Address Information */
891 Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
892 SocketAddressLength,
893 &SocketInfo);
894
895 if (SocketInfo.AddressInfo == SockaddrAddressInfoBroadcast && !Socket->SharedData->Broadcast)
896 {
897 if (lpErrno) *lpErrno = WSAEADDRNOTAVAIL;
898 return SOCKET_ERROR;
899 }
900
903 NULL,
905 FALSE);
906
907 if (!NT_SUCCESS(Status))
908 {
909 return SOCKET_ERROR;
910 }
911
912 /* See below */
913 BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength);
914 if (!BindData)
915 {
917 }
918
919 /* Set up Address in TDI Format */
920 BindData->Address.TAAddressCount = 1;
921 BindData->Address.Address[0].AddressLength = (USHORT)(SocketAddressLength - sizeof(SocketAddress->sa_family));
922 BindData->Address.Address[0].AddressType = SocketAddress->sa_family;
923 RtlCopyMemory (BindData->Address.Address[0].Address,
924 SocketAddress->sa_data,
925 SocketAddressLength - sizeof(SocketAddress->sa_family));
926
927 /* Set the Share Type */
928 if (Socket->SharedData->ExclusiveAddressUse)
929 {
930 BindData->ShareType = AFD_SHARE_EXCLUSIVE;
931 }
932 else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard)
933 {
934 BindData->ShareType = AFD_SHARE_WILDCARD;
935 }
936 else if (Socket->SharedData->ReuseAddresses)
937 {
938 BindData->ShareType = AFD_SHARE_REUSE;
939 }
940 else
941 {
942 BindData->ShareType = AFD_SHARE_UNIQUE;
943 }
944
945 /* Send IOCTL */
947 SockEvent,
948 NULL,
949 NULL,
950 &IOSB,
952 BindData,
953 0xA + Socket->SharedData->SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
954 BindData,
955 0xA + Socket->SharedData->SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
956
957 /* Wait for return */
958 if (Status == STATUS_PENDING)
959 {
961 Status = IOSB.Status;
962 }
963
965 HeapFree(GlobalHeap, 0, BindData);
966
968 if (Status != STATUS_SUCCESS)
969 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
970
971 /* Set up Socket Data */
972 Socket->SharedData->State = SocketBound;
973 Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
974
976 {
977 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
978 Socket->Handle,
979 Socket->TdiAddressHandle,
980 Socket->TdiConnectionHandle,
982
983 if (Status)
984 {
985 if (lpErrno) *lpErrno = Status;
986 return SOCKET_ERROR;
987 }
988 }
989
990 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
991}
992
993int
994WSPAPI
996 int Backlog,
997 LPINT lpErrno)
998{
999 IO_STATUS_BLOCK IOSB;
1000 AFD_LISTEN_DATA ListenData;
1001 PSOCKET_INFORMATION Socket = NULL;
1004
1005 /* Get the Socket Structure associate to this Socket*/
1006 Socket = GetSocketStructure(Handle);
1007 if (!Socket)
1008 {
1009 if (lpErrno) *lpErrno = WSAENOTSOCK;
1010 return SOCKET_ERROR;
1011 }
1012
1013 if (Socket->SharedData->Listening)
1014 return NO_ERROR;
1015
1018 NULL,
1020 FALSE);
1021
1022 if( !NT_SUCCESS(Status) )
1023 return SOCKET_ERROR;
1024
1025 /* Set Up Listen Structure */
1026 ListenData.UseSAN = FALSE;
1028 ListenData.Backlog = Backlog;
1029
1030 /* Send IOCTL */
1032 SockEvent,
1033 NULL,
1034 NULL,
1035 &IOSB,
1037 &ListenData,
1038 sizeof(ListenData),
1039 NULL,
1040 0);
1041
1042 /* Wait for return */
1043 if (Status == STATUS_PENDING)
1044 {
1046 Status = IOSB.Status;
1047 }
1048
1049 NtClose( SockEvent );
1050
1052 if (Status != STATUS_SUCCESS)
1053 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1054
1055 /* Set to Listening */
1056 Socket->SharedData->Listening = TRUE;
1057
1058 if (Socket->HelperEvents & WSH_NOTIFY_LISTEN)
1059 {
1060 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1061 Socket->Handle,
1062 Socket->TdiAddressHandle,
1063 Socket->TdiConnectionHandle,
1065
1066 if (Status)
1067 {
1068 if (lpErrno) *lpErrno = Status;
1069 return SOCKET_ERROR;
1070 }
1071 }
1072
1073 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1074}
1075
1076
1077int
1078WSPAPI
1079WSPSelect(IN int nfds,
1080 IN OUT fd_set *readfds OPTIONAL,
1081 IN OUT fd_set *writefds OPTIONAL,
1082 IN OUT fd_set *exceptfds OPTIONAL,
1083 IN const struct timeval *timeout OPTIONAL,
1084 OUT LPINT lpErrno)
1085{
1086 IO_STATUS_BLOCK IOSB;
1087 PAFD_POLL_INFO PollInfo;
1090 ULONG PollBufferSize;
1091 PVOID PollBuffer;
1092 ULONG i, j = 0, x;
1095 PSOCKET_INFORMATION Socket;
1096 SOCKET Handle;
1097 ULONG Events;
1098 fd_set selectfds;
1099
1100 /* Find out how many sockets we have, and how large the buffer needs
1101 * to be */
1102 FD_ZERO(&selectfds);
1103 if (readfds != NULL)
1104 {
1105 for (i = 0; i < readfds->fd_count; i++)
1106 {
1107 FD_SET(readfds->fd_array[i], &selectfds);
1108 }
1109 }
1110 if (writefds != NULL)
1111 {
1112 for (i = 0; i < writefds->fd_count; i++)
1113 {
1114 FD_SET(writefds->fd_array[i], &selectfds);
1115 }
1116 }
1117 if (exceptfds != NULL)
1118 {
1119 for (i = 0; i < exceptfds->fd_count; i++)
1120 {
1121 FD_SET(exceptfds->fd_array[i], &selectfds);
1122 }
1123 }
1124
1125 HandleCount = selectfds.fd_count;
1126
1127 if ( HandleCount == 0 )
1128 {
1129 WARN("No handles! Returning SOCKET_ERROR\n", HandleCount);
1130 if (lpErrno) *lpErrno = WSAEINVAL;
1131 return SOCKET_ERROR;
1132 }
1133
1134 PollBufferSize = sizeof(*PollInfo) + ((HandleCount - 1) * sizeof(AFD_HANDLE));
1135
1136 TRACE("HandleCount: %u BufferSize: %u\n", HandleCount, PollBufferSize);
1137
1138 /* Convert Timeout to NT Format */
1139 if (timeout == NULL)
1140 {
1141 Timeout.u.LowPart = -1;
1142 Timeout.u.HighPart = 0x7FFFFFFF;
1143 TRACE("Infinite timeout\n");
1144 }
1145 else
1146 {
1148 ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000), -10000);
1149 /* Negative timeouts are illegal. Since the kernel represents an
1150 * incremental timeout as a negative number, we check for a positive
1151 * result.
1152 */
1153 if (Timeout.QuadPart > 0)
1154 {
1155 if (lpErrno) *lpErrno = WSAEINVAL;
1156 return SOCKET_ERROR;
1157 }
1158 TRACE("Timeout: Orig %d.%06d kernel %d\n",
1159 timeout->tv_sec, timeout->tv_usec,
1160 Timeout.u.LowPart);
1161 }
1162
1165 NULL,
1167 FALSE);
1168
1169 if(!NT_SUCCESS(Status))
1170 {
1171 if (lpErrno)
1172 *lpErrno = WSAEFAULT;
1173
1174 ERR("NtCreateEvent failed, 0x%08x\n", Status);
1175 return SOCKET_ERROR;
1176 }
1177
1178 /* Allocate */
1179 PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
1180
1181 if (!PollBuffer)
1182 {
1183 if (lpErrno)
1184 *lpErrno = WSAEFAULT;
1186 return SOCKET_ERROR;
1187 }
1188
1189 PollInfo = (PAFD_POLL_INFO)PollBuffer;
1190
1191 RtlZeroMemory( PollInfo, PollBufferSize );
1192
1193 /* Number of handles for AFD to Check */
1194 PollInfo->Exclusive = FALSE;
1195 PollInfo->Timeout = Timeout;
1196
1197 for (i = 0; i < selectfds.fd_count; i++)
1198 {
1199 PollInfo->Handles[i].Handle = selectfds.fd_array[i];
1200 }
1201 if (readfds != NULL) {
1202 for (i = 0; i < readfds->fd_count; i++)
1203 {
1204 for (j = 0; j < HandleCount; j++)
1205 {
1206 if (PollInfo->Handles[j].Handle == readfds->fd_array[i])
1207 break;
1208 }
1209 if (j >= HandleCount)
1210 {
1211 ERR("Error while counting readfds %ld > %ld\n", j, HandleCount);
1212 if (lpErrno) *lpErrno = WSAEFAULT;
1213 HeapFree(GlobalHeap, 0, PollBuffer);
1215 return SOCKET_ERROR;
1216 }
1217 Socket = GetSocketStructure(readfds->fd_array[i]);
1218 if (!Socket)
1219 {
1220 ERR("Invalid socket handle provided in readfds %d\n", readfds->fd_array[i]);
1221 if (lpErrno) *lpErrno = WSAENOTSOCK;
1222 HeapFree(GlobalHeap, 0, PollBuffer);
1224 return SOCKET_ERROR;
1225 }
1226 PollInfo->Handles[j].Events |= AFD_EVENT_RECEIVE |
1231 //if (Socket->SharedData->OobInline != 0)
1232 // PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
1233 }
1234 }
1235 if (writefds != NULL)
1236 {
1237 for (i = 0; i < writefds->fd_count; i++)
1238 {
1239 for (j = 0; j < HandleCount; j++)
1240 {
1241 if (PollInfo->Handles[j].Handle == writefds->fd_array[i])
1242 break;
1243 }
1244 if (j >= HandleCount)
1245 {
1246 ERR("Error while counting writefds %ld > %ld\n", j, HandleCount);
1247 if (lpErrno) *lpErrno = WSAEFAULT;
1248 HeapFree(GlobalHeap, 0, PollBuffer);
1250 return SOCKET_ERROR;
1251 }
1252 Socket = GetSocketStructure(writefds->fd_array[i]);
1253 if (!Socket)
1254 {
1255 ERR("Invalid socket handle provided in writefds %d\n", writefds->fd_array[i]);
1256 if (lpErrno) *lpErrno = WSAENOTSOCK;
1257 HeapFree(GlobalHeap, 0, PollBuffer);
1259 return SOCKET_ERROR;
1260 }
1261 PollInfo->Handles[j].Handle = writefds->fd_array[i];
1262 PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
1263 if (Socket->SharedData->NonBlocking != 0)
1264 PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT;
1265 }
1266 }
1267 if (exceptfds != NULL)
1268 {
1269 for (i = 0; i < exceptfds->fd_count; i++)
1270 {
1271 for (j = 0; j < HandleCount; j++)
1272 {
1273 if (PollInfo->Handles[j].Handle == exceptfds->fd_array[i])
1274 break;
1275 }
1276 if (j > HandleCount)
1277 {
1278 ERR("Error while counting exceptfds %ld > %ld\n", j, HandleCount);
1279 if (lpErrno) *lpErrno = WSAEFAULT;
1280 HeapFree(GlobalHeap, 0, PollBuffer);
1282 return SOCKET_ERROR;
1283 }
1284 Socket = GetSocketStructure(exceptfds->fd_array[i]);
1285 if (!Socket)
1286 {
1287 TRACE("Invalid socket handle provided in exceptfds %d\n", exceptfds->fd_array[i]);
1288 if (lpErrno) *lpErrno = WSAENOTSOCK;
1289 HeapFree(GlobalHeap, 0, PollBuffer);
1291 return SOCKET_ERROR;
1292 }
1293 PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
1294 if (Socket->SharedData->OobInline == 0)
1295 PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
1296 if (Socket->SharedData->NonBlocking != 0)
1297 PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT_FAIL;
1298 }
1299 }
1300
1301 PollInfo->HandleCount = HandleCount;
1302 PollBufferSize = FIELD_OFFSET(AFD_POLL_INFO, Handles) + PollInfo->HandleCount * sizeof(AFD_HANDLE);
1303
1304 /* Send IOCTL */
1306 SockEvent,
1307 NULL,
1308 NULL,
1309 &IOSB,
1311 PollInfo,
1312 PollBufferSize,
1313 PollInfo,
1314 PollBufferSize);
1315
1316 TRACE("DeviceIoControlFile => %x\n", Status);
1317
1318 /* Wait for Completion */
1319 if (Status == STATUS_PENDING)
1320 {
1322 Status = IOSB.Status;
1323 }
1324
1325 /* Clear the Structures */
1326 if( readfds )
1327 FD_ZERO(readfds);
1328 if( writefds )
1329 FD_ZERO(writefds);
1330 if( exceptfds )
1331 FD_ZERO(exceptfds);
1332
1333 /* Loop through return structure */
1334 HandleCount = PollInfo->HandleCount;
1335
1336 /* Return in FDSET Format */
1337 for (i = 0; i < HandleCount; i++)
1338 {
1339 Events = PollInfo->Handles[i].Events;
1340 Handle = PollInfo->Handles[i].Handle;
1341 for(x = 1; x; x<<=1)
1342 {
1343 Socket = GetSocketStructure(Handle);
1344 if (!Socket)
1345 {
1346 TRACE("Invalid socket handle found %d\n", Handle);
1347 if (lpErrno) *lpErrno = WSAENOTSOCK;
1348 HeapFree(GlobalHeap, 0, PollBuffer);
1350 return SOCKET_ERROR;
1351 }
1352 switch (Events & x)
1353 {
1354 case AFD_EVENT_RECEIVE:
1356 case AFD_EVENT_ABORT:
1357 case AFD_EVENT_ACCEPT:
1358 case AFD_EVENT_CLOSE:
1359 TRACE("Event %x on handle %x\n",
1360 Events,
1361 Handle);
1362 if ((Events & x) == AFD_EVENT_DISCONNECT || (Events & x) == AFD_EVENT_CLOSE)
1364 if ((Events & x) == AFD_EVENT_ABORT)
1366 if( readfds )
1367 FD_SET(Handle, readfds);
1368 break;
1369 case AFD_EVENT_SEND:
1370 TRACE("Event %x on handle %x\n",
1371 Events,
1372 Handle);
1373 if (writefds)
1374 FD_SET(Handle, writefds);
1375 break;
1376 case AFD_EVENT_CONNECT:
1377 TRACE("Event %x on handle %x\n",
1378 Events,
1379 Handle);
1380 if( writefds && Socket->SharedData->NonBlocking != 0 )
1381 FD_SET(Handle, writefds);
1382 break;
1384 TRACE("Event %x on handle %x\n",
1385 Events,
1386 Handle);
1387 if( readfds && Socket->SharedData->OobInline != 0 )
1388 FD_SET(Handle, readfds);
1389 if( exceptfds && Socket->SharedData->OobInline == 0 )
1390 FD_SET(Handle, exceptfds);
1391 break;
1393 TRACE("Event %x on handle %x\n",
1394 Events,
1395 Handle);
1396 if( exceptfds && Socket->SharedData->NonBlocking != 0 )
1397 FD_SET(Handle, exceptfds);
1398 break;
1399 }
1400 }
1401 }
1402
1403 HeapFree( GlobalHeap, 0, PollBuffer );
1404 NtClose( SockEvent );
1405
1406 if( lpErrno )
1407 {
1408 switch( IOSB.Status )
1409 {
1410 case STATUS_SUCCESS:
1411 case STATUS_TIMEOUT:
1412 *lpErrno = 0;
1413 break;
1414 default:
1415 *lpErrno = WSAEINVAL;
1416 break;
1417 }
1418 TRACE("*lpErrno = %x\n", *lpErrno);
1419 }
1420
1421 HandleCount = (readfds ? readfds->fd_count : 0) +
1422 (writefds && writefds != readfds ? writefds->fd_count : 0) +
1423 (exceptfds && exceptfds != readfds && exceptfds != writefds ? exceptfds->fd_count : 0);
1424
1425 TRACE("%d events\n", HandleCount);
1426
1427 return HandleCount;
1428}
1429
1430DWORD
1432{
1433 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
1434 union
1435 {
1436 FILETIME ft;
1437 ULONGLONG ll;
1438 } u1970, Time;
1439
1441 SystemTimeToFileTime(&st1970, &u1970.ft);
1442 return (DWORD)((Time.ll - u1970.ll) / 10000000ULL);
1443}
1444
1446SOCKET
1447WSPAPI
1450 _Out_writes_bytes_to_opt_(*addrlen, *addrlen) struct sockaddr FAR *SocketAddress,
1451 _Inout_opt_ LPINT SocketAddressLength,
1452 _In_opt_ LPCONDITIONPROC lpfnCondition,
1453 _In_opt_ DWORD_PTR dwCallbackData,
1454 _Out_ LPINT lpErrno)
1455{
1456 IO_STATUS_BLOCK IOSB;
1457 PAFD_RECEIVED_ACCEPT_DATA ListenReceiveData;
1458 AFD_ACCEPT_DATA AcceptData;
1459 AFD_DEFER_ACCEPT_DATA DeferData;
1460 AFD_PENDING_ACCEPT_DATA PendingAcceptData;
1461 PSOCKET_INFORMATION Socket = NULL;
1463 struct fd_set ReadSet;
1464 struct timeval Timeout;
1465 PVOID PendingData = NULL;
1466 ULONG PendingDataLength = 0;
1467 PVOID CalleeDataBuffer;
1468 WSABUF CallerData, CalleeID, CallerID, CalleeData;
1470 GROUP GroupID = 0;
1471 ULONG CallBack;
1473 PSOCKET_INFORMATION AcceptSocketInfo;
1474 UCHAR ReceiveBuffer[0x1A];
1476
1477 /* Get the Socket Structure associate to this Socket*/
1478 Socket = GetSocketStructure(Handle);
1479 if (!Socket)
1480 {
1481 if (lpErrno) *lpErrno = WSAENOTSOCK;
1482 return SOCKET_ERROR;
1483 }
1484 if (!Socket->SharedData->Listening)
1485 {
1486 if (lpErrno) *lpErrno = WSAEINVAL;
1487 return SOCKET_ERROR;
1488 }
1489 if ((SocketAddress && !SocketAddressLength) ||
1490 (SocketAddressLength && !SocketAddress) ||
1491 (SocketAddressLength && *SocketAddressLength < sizeof(SOCKADDR)))
1492 {
1493 if (lpErrno) *lpErrno = WSAEFAULT;
1494 return INVALID_SOCKET;
1495 }
1496
1499 NULL,
1501 FALSE);
1502
1503 if( !NT_SUCCESS(Status) )
1504 {
1505 return SOCKET_ERROR;
1506 }
1507
1508 /* Dynamic Structure...ugh */
1509 ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
1510
1511 /* If this is non-blocking, make sure there's something for us to accept */
1512 if (Socket->SharedData->NonBlocking)
1513 {
1514 FD_ZERO(&ReadSet);
1515 FD_SET(Socket->Handle, &ReadSet);
1516 Timeout.tv_sec=0;
1517 Timeout.tv_usec=0;
1518
1519 if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
1520 {
1522 return SOCKET_ERROR;
1523 }
1524
1525 if (ReadSet.fd_array[0] != Socket->Handle)
1526 {
1528 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
1529 return SOCKET_ERROR;
1530 }
1531 }
1532
1533 /* Send IOCTL */
1535 SockEvent,
1536 NULL,
1537 NULL,
1538 &IOSB,
1540 NULL,
1541 0,
1542 ListenReceiveData,
1543 0xA + sizeof(*ListenReceiveData));
1544
1545 /* Wait for return */
1546 if (Status == STATUS_PENDING)
1547 {
1549 Status = IOSB.Status;
1550 }
1551
1552 if (!NT_SUCCESS(Status))
1553 {
1554 NtClose( SockEvent );
1555 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1556 }
1557
1558 if (lpfnCondition != NULL)
1559 {
1560 if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECT_DATA) != 0)
1561 {
1562 /* Find out how much data is pending */
1563 PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1564 PendingAcceptData.ReturnSize = TRUE;
1565
1566 /* Send IOCTL */
1568 SockEvent,
1569 NULL,
1570 NULL,
1571 &IOSB,
1573 &PendingAcceptData,
1574 sizeof(PendingAcceptData),
1575 &PendingAcceptData,
1576 sizeof(PendingAcceptData));
1577
1578 /* Wait for return */
1579 if (Status == STATUS_PENDING)
1580 {
1582 Status = IOSB.Status;
1583 }
1584
1585 if (!NT_SUCCESS(Status))
1586 {
1587 NtClose( SockEvent );
1588 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1589 }
1590
1591 /* How much data to allocate */
1592 PendingDataLength = IOSB.Information;
1593
1594 if (PendingDataLength)
1595 {
1596 /* Allocate needed space */
1597 PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
1598 if (!PendingData)
1599 {
1601 }
1602
1603 /* We want the data now */
1604 PendingAcceptData.ReturnSize = FALSE;
1605
1606 /* Send IOCTL */
1608 SockEvent,
1609 NULL,
1610 NULL,
1611 &IOSB,
1613 &PendingAcceptData,
1614 sizeof(PendingAcceptData),
1615 PendingData,
1616 PendingDataLength);
1617
1618 /* Wait for return */
1619 if (Status == STATUS_PENDING)
1620 {
1622 Status = IOSB.Status;
1623 }
1624
1625 if (!NT_SUCCESS(Status))
1626 {
1627 NtClose( SockEvent );
1628 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1629 }
1630 }
1631 }
1632
1633 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1634 {
1635 /* I don't support this yet */
1636 }
1637
1638 /* Build Callee ID */
1639 CalleeID.buf = (PVOID)Socket->LocalAddress;
1640 CalleeID.len = Socket->SharedData->SizeOfLocalAddress;
1641
1643 if (!RemoteAddress)
1644 {
1646 }
1647
1648 /* Set up Address in SOCKADDR Format */
1650 &ListenReceiveData->Address.Address[0].AddressType,
1651 sizeof(*RemoteAddress));
1652
1653 /* Build Caller ID */
1654 CallerID.buf = (PVOID)RemoteAddress;
1655 CallerID.len = sizeof(*RemoteAddress);
1656
1657 /* Build Caller Data */
1658 CallerData.buf = PendingData;
1659 CallerData.len = PendingDataLength;
1660
1661 /* Check if socket supports Conditional Accept */
1662 if (Socket->SharedData->UseDelayedAcceptance != 0)
1663 {
1664 /* Allocate Buffer for Callee Data */
1665 CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
1666 if (!CalleeDataBuffer) {
1668 }
1669 CalleeData.buf = CalleeDataBuffer;
1670 CalleeData.len = 4096;
1671 }
1672 else
1673 {
1674 /* Nothing */
1675 CalleeData.buf = 0;
1676 CalleeData.len = 0;
1677 }
1678
1679 /* Call the Condition Function */
1680 CallBack = (lpfnCondition)(&CallerID,
1681 CallerData.buf == NULL ? NULL : &CallerData,
1682 NULL,
1683 NULL,
1684 &CalleeID,
1685 CalleeData.buf == NULL ? NULL : &CalleeData,
1686 &GroupID,
1687 dwCallbackData);
1688
1689 if (((CallBack == CF_ACCEPT) && GroupID) != 0)
1690 {
1691 /* TBD: Check for Validity */
1692 }
1693
1694 if (CallBack == CF_ACCEPT)
1695 {
1696 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1697 {
1698 /* I don't support this yet */
1699 }
1700 if (CalleeData.buf)
1701 {
1702 // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0
1703 }
1704 }
1705 else
1706 {
1707 /* Callback rejected. Build Defer Structure */
1708 DeferData.SequenceNumber = ListenReceiveData->SequenceNumber;
1709 DeferData.RejectConnection = (CallBack == CF_REJECT);
1710
1711 /* Send IOCTL */
1713 SockEvent,
1714 NULL,
1715 NULL,
1716 &IOSB,
1718 &DeferData,
1719 sizeof(DeferData),
1720 NULL,
1721 0);
1722
1723 /* Wait for return */
1724 if (Status == STATUS_PENDING)
1725 {
1727 Status = IOSB.Status;
1728 }
1729
1730 NtClose( SockEvent );
1731
1732 if (!NT_SUCCESS(Status))
1733 {
1734 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1735 }
1736
1737 if (CallBack == CF_REJECT )
1738 {
1739 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1740 return SOCKET_ERROR;
1741 }
1742 else
1743 {
1744 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1745 return SOCKET_ERROR;
1746 }
1747 }
1748 }
1749
1750 /* Create a new Socket */
1752 Socket->SharedData->SocketType,
1753 Socket->SharedData->Protocol,
1754 &Socket->ProtocolInfo,
1755 GroupID,
1756 Socket->SharedData->CreateFlags,
1757 lpErrno);
1759 return SOCKET_ERROR;
1760
1761 /* Set up the Accept Structure */
1762 AcceptData.ListenHandle = (HANDLE)AcceptSocket;
1763 AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1764
1765 /* Send IOCTL to Accept */
1767 SockEvent,
1768 NULL,
1769 NULL,
1770 &IOSB,
1772 &AcceptData,
1773 sizeof(AcceptData),
1774 NULL,
1775 0);
1776
1777 /* Wait for return */
1778 if (Status == STATUS_PENDING)
1779 {
1781 Status = IOSB.Status;
1782 }
1783
1785 if (!NT_SUCCESS(Status))
1786 {
1788 WSPCloseSocket( AcceptSocket, lpErrno );
1789 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1790 }
1791
1792 AcceptSocketInfo = GetSocketStructure(AcceptSocket);
1793 if (!AcceptSocketInfo)
1794 {
1796 WSPCloseSocket( AcceptSocket, lpErrno );
1798 }
1799
1800 AcceptSocketInfo->SharedData->State = SocketConnected;
1801 AcceptSocketInfo->SharedData->ConnectTime = GetCurrentTimeInSeconds();
1802 AcceptSocketInfo->SharedData->NonBlocking = Socket->SharedData->NonBlocking;
1803
1804 /* Return Address in SOCKADDR FORMAT */
1805 if( SocketAddress )
1806 {
1807 RtlCopyMemory (SocketAddress,
1808 &ListenReceiveData->Address.Address[0].AddressType,
1809 sizeof(*RemoteAddress));
1810 if( SocketAddressLength )
1811 *SocketAddressLength = sizeof(*RemoteAddress);
1812 }
1813
1814 NtClose( SockEvent );
1815
1816 /* Re-enable Async Event */
1818
1819 TRACE("Socket %x\n", AcceptSocket);
1820
1822 {
1823 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1824 Socket->Handle,
1825 Socket->TdiAddressHandle,
1826 Socket->TdiConnectionHandle,
1828
1829 if (Status)
1830 {
1831 if (lpErrno) *lpErrno = Status;
1832 return SOCKET_ERROR;
1833 }
1834 }
1835
1836 if (lpErrno) *lpErrno = NO_ERROR;
1837
1838 /* Return Socket */
1839 return AcceptSocket;
1840}
1841
1842static
1843VOID
1844NTAPI
1849{
1851
1852 TRACE("MsafdConnectAPC(%p %lx %lx)\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information);
1853
1855 if (!Socket)
1856 {
1857 // FIXME: Socket is closed before this APC could run
1859 return;
1860 }
1861
1864 {
1865 Socket->SharedData->State = SocketConnected;
1868 }
1869
1870 /* Re-enable Async Event */
1872
1873 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
1875
1877 {
1878 Socket->HelperData->WSHNotify(Socket->HelperContext,
1879 Socket->Handle,
1880 Socket->TdiAddressHandle,
1881 Socket->TdiConnectionHandle,
1883 }
1885 {
1886 Socket->HelperData->WSHNotify(Socket->HelperContext,
1887 Socket->Handle,
1888 Socket->TdiAddressHandle,
1889 Socket->TdiConnectionHandle,
1891 }
1892
1894}
1895
1896int
1897WSPAPI
1899 const struct sockaddr * SocketAddress,
1900 int SocketAddressLength,
1901 LPWSABUF lpCallerData,
1902 LPWSABUF lpCalleeData,
1903 LPQOS lpSQOS,
1904 LPQOS lpGQOS,
1905 LPINT lpErrno)
1906{
1907 IO_STATUS_BLOCK DummyIOSB;
1908 PIO_STATUS_BLOCK IOSB = &DummyIOSB;
1909 PAFD_CONNECT_INFO ConnectInfo = NULL;
1910 PSOCKET_INFORMATION Socket;
1912 INT Errno;
1913 ULONG ConnectDataLength;
1914 ULONG InConnectDataLength;
1916 int SocketDataLength;
1917 PMSAFD_CONNECT_APC_CONTEXT APCContext = NULL;
1918 PIO_APC_ROUTINE APCFunction = NULL;
1919 UCHAR Buffer[128];
1920
1921 TRACE("WSPConnect(%x)\n", Handle);
1922
1923 /* Get the Socket Structure associate to this Socket*/
1924 Socket = GetSocketStructure(Handle);
1925 if (!Socket)
1926 {
1927 if (lpErrno) *lpErrno = WSAENOTSOCK;
1928 return SOCKET_ERROR;
1929 }
1930
1931 /* Bind us First */
1932 if (Socket->SharedData->State == SocketOpen)
1933 {
1934 INT BindAddressLength;
1935 PSOCKADDR BindAddress;
1936 INT BindError;
1937
1938 /* Get the Wildcard Address */
1939 BindAddressLength = Socket->HelperData->MaxWSAddressLength;
1940 BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength);
1941 if (!BindAddress)
1942 {
1944 }
1946 BindAddress,
1947 &BindAddressLength);
1948 /* Bind it */
1949 BindError = WSPBind(Handle, BindAddress, BindAddressLength, lpErrno);
1950 HeapFree(GetProcessHeap(), 0, BindAddress);
1951 if (BindError == SOCKET_ERROR)
1952 return SOCKET_ERROR;
1953 }
1954
1957 NULL,
1959 FALSE);
1960 if (!NT_SUCCESS(Status))
1961 return SOCKET_ERROR;
1962
1963 /* Set the Connect Data */
1964 if (lpCallerData != NULL)
1965 {
1966 ConnectDataLength = lpCallerData->len;
1968 SockEvent,
1969 NULL,
1970 NULL,
1971 IOSB,
1973 lpCallerData->buf,
1974 ConnectDataLength,
1975 NULL,
1976 0);
1977 /* Wait for return */
1978 if (Status == STATUS_PENDING)
1979 {
1981 Status = IOSB->Status;
1982 }
1983
1984 if (Status != STATUS_SUCCESS)
1985 goto Leave;
1986 }
1987
1988 /* Calculate the size of SocketAddress->sa_data */
1989 SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
1990
1991 ConnectInfo = (PAFD_CONNECT_INFO)Buffer;
1992
1993 int connectionInfoSize = FIELD_OFFSET(AFD_CONNECT_INFO, RemoteAddress.Address[0].Address[SocketDataLength]);
1994
1995 if (connectionInfoSize > 128)
1996 {
1997 *lpErrno = WSAEFAULT;
1998 return SOCKET_ERROR;
1999 }
2000
2001 /* Set up Address in TDI Format */
2002 ConnectInfo->RemoteAddress.TAAddressCount = 1;
2003 ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
2004 ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
2006 SocketAddress->sa_data,
2007 SocketDataLength);
2008
2009 /*
2010 * Disable FD_WRITE and FD_CONNECT
2011 * The latter fixes a race condition where the FD_CONNECT is re-enabled
2012 * at the end of this function right after the Async Thread disables it.
2013 * This should only happen at the *next* WSPConnect
2014 */
2015 if (Socket->SharedData->AsyncEvents & FD_CONNECT)
2016 {
2018 }
2019
2020 /* Tell AFD that we want Connection Data back, have it allocate a buffer */
2021 if (lpCalleeData != NULL)
2022 {
2023 InConnectDataLength = lpCalleeData->len;
2025 SockEvent,
2026 NULL,
2027 NULL,
2028 IOSB,
2030 &InConnectDataLength,
2031 sizeof(InConnectDataLength),
2032 NULL,
2033 0);
2034
2035 /* Wait for return */
2036 if (Status == STATUS_PENDING)
2037 {
2039 Status = IOSB->Status;
2040 }
2041
2042 if (Status != STATUS_SUCCESS)
2043 goto Leave;
2044 }
2045
2046 /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */
2047 ConnectInfo->Root = 0;
2048 ConnectInfo->UseSAN = FALSE;
2049 ConnectInfo->Unknown = 0;
2050
2051 /* Verify if we should use APC */
2052 if (Socket->SharedData->NonBlocking)
2053 {
2054 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
2055 if (!APCContext)
2056 {
2057 ERR("Not enough memory for APC Context\n");
2059 goto Leave;
2060 }
2061 APCContext->lpSocket = Handle;
2062 APCFunction = &MsafdConnectAPC;
2063
2064 IOSB = &APCContext->IoStatusBlock;
2065 }
2066
2067 IOSB->Status = STATUS_PENDING;
2068 IOSB->Information = 0;
2069
2070 /* Send IOCTL */
2072 APCFunction ? NULL : SockEvent,
2073 APCFunction,
2074 APCContext,
2075 IOSB,
2077 ConnectInfo,
2078 connectionInfoSize,
2079 NULL,
2080 0);
2081 if (Socket->SharedData->NonBlocking)
2082 {
2083 if (Status == STATUS_PENDING)
2084 {
2085 Status = STATUS_CANT_WAIT; // WSAEWOULDBLOCK
2086 goto Leave;
2087 }
2088 else
2089 {
2090 /* HACK: Allow APC to be processed */
2091 SleepEx(0, TRUE);
2092 }
2093 }
2094 else
2095 {
2096 /* Wait for completion if blocking */
2097 if (Status == STATUS_PENDING)
2098 {
2100 Status = IOSB->Status;
2101 }
2102
2104 if (Status != STATUS_SUCCESS)
2105 goto Leave;
2106
2107 Socket->SharedData->State = SocketConnected;
2108 Socket->TdiConnectionHandle = (HANDLE)IOSB->Information;
2110 }
2111
2112 /* Get any pending connect data */
2113 if (lpCalleeData != NULL && Status == STATUS_SUCCESS)
2114 {
2115 IOSB = &DummyIOSB;
2117 SockEvent,
2118 NULL,
2119 NULL,
2120 IOSB,
2122 NULL,
2123 0,
2124 lpCalleeData->buf,
2125 lpCalleeData->len);
2126 /* Wait for return */
2127 if (Status == STATUS_PENDING)
2128 {
2130 Status = IOSB->Status;
2131 }
2132 }
2133
2134Leave:
2135 TRACE("Ending %lx\n", Status);
2136
2138
2139 /* Re-enable Async Event */
2141
2142 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
2144
2146 {
2147 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2148 Socket->Handle,
2149 Socket->TdiAddressHandle,
2150 Socket->TdiConnectionHandle,
2152
2153 if (Errno)
2154 {
2155 if (lpErrno) *lpErrno = Errno;
2156 return SOCKET_ERROR;
2157 }
2158 }
2160 {
2161 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2162 Socket->Handle,
2163 Socket->TdiAddressHandle,
2164 Socket->TdiConnectionHandle,
2166
2167 if (Errno)
2168 {
2169 if (lpErrno) *lpErrno = Errno;
2170 return SOCKET_ERROR;
2171 }
2172 }
2173
2174 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
2175}
2176int
2177WSPAPI
2179 int HowTo,
2180 LPINT lpErrno)
2181
2182{
2183 IO_STATUS_BLOCK IOSB;
2184 AFD_DISCONNECT_INFO DisconnectInfo;
2185 PSOCKET_INFORMATION Socket = NULL;
2188
2189 TRACE("Called\n");
2190
2191 /* Get the Socket Structure associate to this Socket*/
2192 Socket = GetSocketStructure(Handle);
2193 if (!Socket)
2194 {
2195 if (lpErrno) *lpErrno = WSAENOTSOCK;
2196 return SOCKET_ERROR;
2197 }
2198
2201 NULL,
2203 FALSE);
2204
2205 if( !NT_SUCCESS(Status) )
2206 return SOCKET_ERROR;
2207
2208 /* Set AFD Disconnect Type */
2209 switch (HowTo)
2210 {
2211 case SD_RECEIVE:
2212 DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
2213 Socket->SharedData->ReceiveShutdown = TRUE;
2214 break;
2215 case SD_SEND:
2216 DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
2217 Socket->SharedData->SendShutdown = TRUE;
2218 break;
2219 case SD_BOTH:
2221 Socket->SharedData->ReceiveShutdown = TRUE;
2222 Socket->SharedData->SendShutdown = TRUE;
2223 break;
2224 }
2225
2226 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1000000);
2227
2228 /* Send IOCTL */
2230 SockEvent,
2231 NULL,
2232 NULL,
2233 &IOSB,
2235 &DisconnectInfo,
2236 sizeof(DisconnectInfo),
2237 NULL,
2238 0);
2239
2240 /* Wait for return */
2241 if (Status == STATUS_PENDING)
2242 {
2244 Status = IOSB.Status;
2245 }
2246
2247 TRACE("Ending\n");
2248
2249 NtClose( SockEvent );
2250
2252 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
2253}
2254
2255
2256INT
2257WSPAPI
2260 IN OUT LPINT NameLength,
2261 OUT LPINT lpErrno)
2262{
2263 IO_STATUS_BLOCK IOSB;
2264 ULONG TdiAddressSize;
2265 PTDI_ADDRESS_INFO TdiAddress;
2266 PTRANSPORT_ADDRESS SocketAddress;
2267 PSOCKET_INFORMATION Socket = NULL;
2270
2271 /* Get the Socket Structure associate to this Socket*/
2272 Socket = GetSocketStructure(Handle);
2273 if (!Socket)
2274 {
2275 if (lpErrno) *lpErrno = WSAENOTSOCK;
2276 return SOCKET_ERROR;
2277 }
2278
2279 if (!Name || !NameLength)
2280 {
2281 if (lpErrno) *lpErrno = WSAEFAULT;
2282 return SOCKET_ERROR;
2283 }
2284
2287 NULL,
2289 FALSE);
2290
2291 if( !NT_SUCCESS(Status) )
2292 return SOCKET_ERROR;
2293
2294 /* Allocate a buffer for the address */
2295 TdiAddressSize =
2297 TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2298
2299 if ( TdiAddress == NULL )
2300 {
2301 NtClose( SockEvent );
2302 if (lpErrno) *lpErrno = WSAENOBUFS;
2303 return SOCKET_ERROR;
2304 }
2305
2306 SocketAddress = &TdiAddress->Address;
2307
2308 /* Send IOCTL */
2310 SockEvent,
2311 NULL,
2312 NULL,
2313 &IOSB,
2315 NULL,
2316 0,
2317 TdiAddress,
2318 TdiAddressSize);
2319
2320 /* Wait for return */
2321 if (Status == STATUS_PENDING)
2322 {
2324 Status = IOSB.Status;
2325 }
2326
2327 NtClose( SockEvent );
2328
2329 if (NT_SUCCESS(Status))
2330 {
2331 if (*NameLength >= Socket->SharedData->SizeOfLocalAddress)
2332 {
2333 Name->sa_family = SocketAddress->Address[0].AddressType;
2334 RtlCopyMemory (Name->sa_data,
2335 SocketAddress->Address[0].Address,
2336 SocketAddress->Address[0].AddressLength);
2337 *NameLength = Socket->SharedData->SizeOfLocalAddress;
2338 TRACE("NameLength %d Address: %x Port %x\n",
2339 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2340 ((struct sockaddr_in *)Name)->sin_port);
2341 HeapFree(GlobalHeap, 0, TdiAddress);
2342 return 0;
2343 }
2344 else
2345 {
2346 HeapFree(GlobalHeap, 0, TdiAddress);
2347 if (lpErrno) *lpErrno = WSAEFAULT;
2348 return SOCKET_ERROR;
2349 }
2350 }
2351
2352 HeapFree(GlobalHeap, 0, TdiAddress);
2353
2354 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2355}
2356
2357
2358INT
2359WSPAPI
2362 IN OUT LPINT NameLength,
2363 OUT LPINT lpErrno)
2364{
2365 IO_STATUS_BLOCK IOSB;
2366 ULONG TdiAddressSize;
2367 PTRANSPORT_ADDRESS SocketAddress;
2368 PSOCKET_INFORMATION Socket = NULL;
2371
2372 /* Get the Socket Structure associate to this Socket*/
2373 Socket = GetSocketStructure(s);
2374 if (!Socket)
2375 {
2376 if (lpErrno) *lpErrno = WSAENOTSOCK;
2377 return SOCKET_ERROR;
2378 }
2379
2380 if (Socket->SharedData->State != SocketConnected)
2381 {
2382 if (lpErrno) *lpErrno = WSAENOTCONN;
2383 return SOCKET_ERROR;
2384 }
2385
2386 if (!Name || !NameLength)
2387 {
2388 if (lpErrno) *lpErrno = WSAEFAULT;
2389 return SOCKET_ERROR;
2390 }
2391
2394 NULL,
2396 FALSE);
2397
2398 if( !NT_SUCCESS(Status) )
2399 return SOCKET_ERROR;
2400
2401 /* Allocate a buffer for the address */
2402 TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress;
2403 SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2404
2405 if ( SocketAddress == NULL )
2406 {
2407 NtClose( SockEvent );
2408 if (lpErrno) *lpErrno = WSAENOBUFS;
2409 return SOCKET_ERROR;
2410 }
2411
2412 /* Send IOCTL */
2414 SockEvent,
2415 NULL,
2416 NULL,
2417 &IOSB,
2419 NULL,
2420 0,
2421 SocketAddress,
2422 TdiAddressSize);
2423
2424 /* Wait for return */
2425 if (Status == STATUS_PENDING)
2426 {
2428 Status = IOSB.Status;
2429 }
2430
2431 NtClose( SockEvent );
2432
2433 if (NT_SUCCESS(Status))
2434 {
2435 if (*NameLength >= Socket->SharedData->SizeOfRemoteAddress)
2436 {
2437 Name->sa_family = SocketAddress->Address[0].AddressType;
2438 RtlCopyMemory (Name->sa_data,
2439 SocketAddress->Address[0].Address,
2440 SocketAddress->Address[0].AddressLength);
2441 *NameLength = Socket->SharedData->SizeOfRemoteAddress;
2442 TRACE("NameLength %d Address: %x Port %x\n",
2443 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2444 ((struct sockaddr_in *)Name)->sin_port);
2445 HeapFree(GlobalHeap, 0, SocketAddress);
2446 return 0;
2447 }
2448 else
2449 {
2450 HeapFree(GlobalHeap, 0, SocketAddress);
2451 if (lpErrno) *lpErrno = WSAEFAULT;
2452 return SOCKET_ERROR;
2453 }
2454 }
2455
2456 HeapFree(GlobalHeap, 0, SocketAddress);
2457
2458 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2459}
2460
2461INT
2462WSPAPI
2465 IN LPVOID lpvInBuffer,
2466 IN DWORD cbInBuffer,
2467 OUT LPVOID lpvOutBuffer,
2468 IN DWORD cbOutBuffer,
2469 OUT LPDWORD lpcbBytesReturned,
2471 IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
2472 IN LPWSATHREADID lpThreadId,
2473 OUT LPINT lpErrno)
2474{
2475 PSOCKET_INFORMATION Socket = NULL;
2476 BOOL NeedsCompletion = lpOverlapped != NULL;
2477 BOOLEAN NonBlocking;
2478 INT Errno = NO_ERROR, Ret = SOCKET_ERROR;
2479 DWORD cbRet = 0;
2480
2481 /* Get the Socket Structure associate to this Socket*/
2482 Socket = GetSocketStructure(Handle);
2483 if (!Socket)
2484 {
2485 if(lpErrno)
2486 *lpErrno = WSAENOTSOCK;
2487 return SOCKET_ERROR;
2488 }
2489
2490 if (!lpcbBytesReturned && !lpOverlapped)
2491 {
2492 if(lpErrno)
2493 *lpErrno = WSAEFAULT;
2494 return SOCKET_ERROR;
2495 }
2496
2497 switch( dwIoControlCode )
2498 {
2499 case FIONBIO:
2500 if( cbInBuffer < sizeof(INT) || IS_INTRESOURCE(lpvInBuffer) )
2501 {
2502 Errno = WSAEFAULT;
2503 break;
2504 }
2505 NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
2506 /* Don't allow to go in blocking mode if WSPAsyncSelect or WSPEventSelect is pending */
2507 if (!NonBlocking)
2508 {
2509 /* If there is an WSPAsyncSelect pending, fail with WSAEINVAL */
2510 if (Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents))
2511 {
2512 Errno = WSAEINVAL;
2513 break;
2514 }
2515 /* If there is an WSPEventSelect pending, fail with WSAEINVAL */
2516 if (Socket->NetworkEvents)
2517 {
2518 Errno = WSAEINVAL;
2519 break;
2520 }
2521 }
2522 Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
2523 NeedsCompletion = FALSE;
2524 Errno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL, lpOverlapped, lpCompletionRoutine);
2525 if (Errno == NO_ERROR)
2526 Ret = NO_ERROR;
2527 break;
2528 case FIONREAD:
2529 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2530 {
2531 cbRet = sizeof(ULONG);
2532 Errno = WSAEFAULT;
2533 break;
2534 }
2535 if (cbOutBuffer < sizeof(ULONG))
2536 {
2537 Errno = WSAEINVAL;
2538 break;
2539 }
2540 NeedsCompletion = FALSE;
2541 Errno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL, lpOverlapped, lpCompletionRoutine);
2542 if (Errno == NO_ERROR)
2543 {
2544 cbRet = sizeof(ULONG);
2545 Ret = NO_ERROR;
2546 }
2547 break;
2548 case SIOCATMARK:
2549 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2550 {
2551 cbRet = sizeof(BOOL);
2552 Errno = WSAEFAULT;
2553 break;
2554 }
2555 if (cbOutBuffer < sizeof(BOOL))
2556 {
2557 Errno = WSAEINVAL;
2558 break;
2559 }
2560 if (Socket->SharedData->SocketType != SOCK_STREAM)
2561 {
2562 Errno = WSAEINVAL;
2563 break;
2564 }
2565
2566 /* FIXME: Return false if OOBINLINE is true for now
2567 We should MSG_PEEK|MSG_OOB check with driver
2568 */
2569 *(BOOL*)lpvOutBuffer = !Socket->SharedData->OobInline;
2570
2571 cbRet = sizeof(BOOL);
2572 Errno = NO_ERROR;
2573 Ret = NO_ERROR;
2574 break;
2576 if (cbOutBuffer == 0)
2577 {
2578 cbRet = sizeof(PVOID);
2579 Errno = WSAEFAULT;
2580 break;
2581 }
2582
2583 if (cbInBuffer < sizeof(GUID) ||
2584 cbOutBuffer < sizeof(PVOID))
2585 {
2586 Errno = WSAEINVAL;
2587 break;
2588 }
2589
2590 {
2591 GUID AcceptExGUID = WSAID_ACCEPTEX;
2592 GUID ConnectExGUID = WSAID_CONNECTEX;
2593 GUID DisconnectExGUID = WSAID_DISCONNECTEX;
2594 GUID GetAcceptExSockaddrsGUID = WSAID_GETACCEPTEXSOCKADDRS;
2595
2596 if (IsEqualGUID(&AcceptExGUID, lpvInBuffer))
2597 {
2598 *((PVOID *)lpvOutBuffer) = WSPAcceptEx;
2599 cbRet = sizeof(PVOID);
2600 Errno = NO_ERROR;
2601 Ret = NO_ERROR;
2602 }
2603 else if (IsEqualGUID(&ConnectExGUID, lpvInBuffer))
2604 {
2605 *((PVOID *)lpvOutBuffer) = WSPConnectEx;
2606 cbRet = sizeof(PVOID);
2607 Errno = NO_ERROR;
2608 Ret = NO_ERROR;
2609 }
2610 else if (IsEqualGUID(&DisconnectExGUID, lpvInBuffer))
2611 {
2612 *((PVOID *)lpvOutBuffer) = WSPDisconnectEx;
2613 cbRet = sizeof(PVOID);
2614 Errno = NO_ERROR;
2615 Ret = NO_ERROR;
2616 }
2617 else if (IsEqualGUID(&GetAcceptExSockaddrsGUID, lpvInBuffer))
2618 {
2619 *((PVOID *)lpvOutBuffer) = WSPGetAcceptExSockaddrs;
2620 cbRet = sizeof(PVOID);
2621 Errno = NO_ERROR;
2622 /* See CORE-14966 and associated commits.
2623 * Original line below was 'Ret = NO_ERROR:'.
2624 * This caused winetest ws2_32:sock to hang.
2625 * This new Ret value allows the test to complete. */
2626 ERR("SIO_GET_EXTENSION_FUNCTION_POINTER UNIMPLEMENTED\n");
2627 Ret = SOCKET_ERROR;
2628 }
2629 else
2630 {
2631 ERR("Querying unknown extension function: %x\n", ((GUID*)lpvInBuffer)->Data1);
2632 Errno = WSAEOPNOTSUPP;
2633 }
2634 }
2635
2636 break;
2638 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2639 {
2640 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2641 Errno = WSAEFAULT;
2642 break;
2643 }
2644 if (cbOutBuffer < sizeof(INT))
2645 {
2646 Errno = WSAEINVAL;
2647 break;
2648 }
2649
2650 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2651
2652 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->iAddressCount = 1;
2653
2654 if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress)))
2655 {
2656 Errno = WSAEFAULT;
2657 break;
2658 }
2659
2660 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->SharedData->WSLocalAddress);
2661 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->SharedData->WSLocalAddress;
2662
2663 Errno = NO_ERROR;
2664 Ret = NO_ERROR;
2665 break;
2666 default:
2667 Errno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
2668 Handle,
2669 Socket->TdiAddressHandle,
2670 Socket->TdiConnectionHandle,
2672 lpvInBuffer,
2673 cbInBuffer,
2674 lpvOutBuffer,
2675 cbOutBuffer,
2676 &cbRet,
2678 lpCompletionRoutine,
2679 &NeedsCompletion);
2680
2681 if (Errno == NO_ERROR)
2682 Ret = NO_ERROR;
2683 break;
2684 }
2685 if (lpOverlapped && NeedsCompletion)
2686 {
2687 lpOverlapped->Internal = Errno;
2688 lpOverlapped->InternalHigh = cbRet;
2689 if (lpCompletionRoutine != NULL)
2690 {
2691 lpCompletionRoutine(Errno, cbRet, lpOverlapped, 0);
2692 }
2693 if (lpOverlapped->hEvent)
2694 SetEvent(lpOverlapped->hEvent);
2696 {
2697 ERR("PostQueuedCompletionStatus failed %d\n", GetLastError());
2698 }
2699 return NO_ERROR;
2700 }
2701 if (lpErrno)
2702 *lpErrno = Errno;
2703 if (lpcbBytesReturned)
2704 *lpcbBytesReturned = cbRet;
2705 return Ret;
2706}
2707
2708
2709INT
2710WSPAPI
2712 IN INT Level,
2713 IN INT OptionName,
2714 OUT CHAR FAR* OptionValue,
2715 IN OUT LPINT OptionLength,
2716 OUT LPINT lpErrno)
2717{
2718 PSOCKET_INFORMATION Socket = NULL;
2719 PVOID Buffer;
2721 BOOL BoolBuffer;
2722 DWORD DwordBuffer;
2723 INT Errno;
2724
2725 TRACE("Called\n");
2726
2727 /* Get the Socket Structure associate to this Socket*/
2728 Socket = GetSocketStructure(Handle);
2729 if (Socket == NULL)
2730 {
2731 if (lpErrno) *lpErrno = WSAENOTSOCK;
2732 return SOCKET_ERROR;
2733 }
2734 if (!OptionLength || !OptionValue)
2735 {
2736 if (lpErrno) *lpErrno = WSAEFAULT;
2737 return SOCKET_ERROR;
2738 }
2739
2740 switch (Level)
2741 {
2742 case SOL_SOCKET:
2743 switch (OptionName)
2744 {
2745 case SO_TYPE:
2746 Buffer = &Socket->SharedData->SocketType;
2747 BufferSize = sizeof(INT);
2748 break;
2749
2750 case SO_RCVBUF:
2752 BufferSize = sizeof(ULONG);
2753 break;
2754
2755 case SO_SNDBUF:
2757 BufferSize = sizeof(ULONG);
2758 break;
2759
2760 case SO_ACCEPTCONN:
2761 BoolBuffer = Socket->SharedData->Listening;
2762 Buffer = &BoolBuffer;
2763 BufferSize = sizeof(BOOL);
2764 break;
2765
2766 case SO_BROADCAST:
2767 BoolBuffer = Socket->SharedData->Broadcast;
2768 Buffer = &BoolBuffer;
2769 BufferSize = sizeof(BOOL);
2770 break;
2771
2772 case SO_DEBUG:
2773 BoolBuffer = Socket->SharedData->Debug;
2774 Buffer = &BoolBuffer;
2775 BufferSize = sizeof(BOOL);
2776 break;
2777
2778 case SO_DONTLINGER:
2779 BoolBuffer = (Socket->SharedData->LingerData.l_onoff == 0);
2780 Buffer = &BoolBuffer;
2781 BufferSize = sizeof(BOOL);
2782 break;
2783
2784 case SO_LINGER:
2785 if (Socket->SharedData->SocketType == SOCK_DGRAM)
2786 {
2787 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
2788 return SOCKET_ERROR;
2789 }
2790 Buffer = &Socket->SharedData->LingerData;
2791 BufferSize = sizeof(struct linger);
2792 break;
2793
2794 case SO_OOBINLINE:
2795 BoolBuffer = (Socket->SharedData->OobInline != 0);
2796 Buffer = &BoolBuffer;
2797 BufferSize = sizeof(BOOL);
2798 break;
2799
2800 case SO_KEEPALIVE:
2801 case SO_DONTROUTE:
2802 /* These guys go directly to the helper */
2803 goto SendToHelper;
2804
2806 BoolBuffer = (Socket->SharedData->UseDelayedAcceptance != 0);
2807 Buffer = &BoolBuffer;
2808 BufferSize = sizeof(BOOL);
2809 break;
2810
2811 case SO_REUSEADDR:
2812 BoolBuffer = (Socket->SharedData->ReuseAddresses != 0);
2813 Buffer = &BoolBuffer;
2814 BufferSize = sizeof(BOOL);
2815 break;
2816
2818 BoolBuffer = (Socket->SharedData->ExclusiveAddressUse != 0);
2819 Buffer = &BoolBuffer;
2820 BufferSize = sizeof(BOOL);
2821 break;
2822
2823 case SO_ERROR:
2824 Buffer = &Socket->SharedData->SocketLastError;
2825 BufferSize = sizeof(INT);
2826 break;
2827
2828 case SO_CONNECT_TIME:
2829 DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
2830 Buffer = &DwordBuffer;
2831 BufferSize = sizeof(DWORD);
2832 break;
2833
2834 case SO_SNDTIMEO:
2835 Buffer = &Socket->SharedData->SendTimeout;
2836 BufferSize = sizeof(DWORD);
2837 break;
2838 case SO_RCVTIMEO:
2839 Buffer = &Socket->SharedData->RecvTimeout;
2840 BufferSize = sizeof(DWORD);
2841 break;
2842 case SO_PROTOCOL_INFOW:
2843 Buffer = &Socket->ProtocolInfo;
2844 BufferSize = sizeof(Socket->ProtocolInfo);
2845 break;
2846
2847 case SO_GROUP_ID:
2848 case SO_GROUP_PRIORITY:
2849 case SO_MAX_MSG_SIZE:
2850
2851 default:
2852 DbgPrint("MSAFD: Get unknown optname %x\n", OptionName);
2853 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
2854 return SOCKET_ERROR;
2855 }
2856
2857 if (*OptionLength < BufferSize)
2858 {
2859 if (lpErrno) *lpErrno = WSAEFAULT;
2860 *OptionLength = BufferSize;
2861 return SOCKET_ERROR;
2862 }
2863 RtlCopyMemory(OptionValue, Buffer, BufferSize);
2864
2865 return 0;
2866
2867 default:
2868 if (lpErrno) *lpErrno = WSAEINVAL;
2869 return SOCKET_ERROR;
2870 }
2871
2872SendToHelper:
2873 Errno = Socket->HelperData->WSHGetSocketInformation(Socket->HelperContext,
2874 Handle,
2875 Socket->TdiAddressHandle,
2876 Socket->TdiConnectionHandle,
2877 Level,
2878 OptionName,
2879 OptionValue,
2880 (LPINT)OptionLength);
2881 if (lpErrno) *lpErrno = Errno;
2882 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
2883}
2884
2885INT
2886WSPAPI
2888 IN SOCKET s,
2889 IN INT level,
2890 IN INT optname,
2891 IN CONST CHAR FAR* optval,
2892 IN INT optlen,
2893 OUT LPINT lpErrno)
2894{
2895 PSOCKET_INFORMATION Socket;
2896 INT Errno;
2897
2898 /* Get the Socket Structure associate to this Socket*/
2899 Socket = GetSocketStructure(s);
2900 if (Socket == NULL)
2901 {
2902 if (lpErrno) *lpErrno = WSAENOTSOCK;
2903 return SOCKET_ERROR;
2904 }
2905 if (!optval)
2906 {
2907 if (lpErrno) *lpErrno = WSAEFAULT;
2908 return SOCKET_ERROR;
2909 }
2910
2911
2912 /* FIXME: We should handle some more cases here */
2913 if (level == SOL_SOCKET)
2914 {
2915 switch (optname)
2916 {
2917 case SO_BROADCAST:
2918 if (optlen < sizeof(BOOL))
2919 {
2920 if (lpErrno) *lpErrno = WSAEFAULT;
2921 return SOCKET_ERROR;
2922 }
2923 Socket->SharedData->Broadcast = (*optval != 0) ? 1 : 0;
2924 return NO_ERROR;
2925
2926 case SO_OOBINLINE:
2927 if (optlen < sizeof(BOOL))
2928 {
2929 if (lpErrno) *lpErrno = WSAEFAULT;
2930 return SOCKET_ERROR;
2931 }
2932 Socket->SharedData->OobInline = (*optval != 0) ? 1 : 0;
2933 return NO_ERROR;
2934
2935 case SO_DONTLINGER:
2936 if (optlen < sizeof(BOOL))
2937 {
2938 if (lpErrno) *lpErrno = WSAEFAULT;
2939 return SOCKET_ERROR;
2940 }
2941 Socket->SharedData->LingerData.l_onoff = (*optval != 0) ? 0 : 1;
2942 return NO_ERROR;
2943
2944 case SO_REUSEADDR:
2945 if (optlen < sizeof(BOOL))
2946 {
2947 if (lpErrno) *lpErrno = WSAEFAULT;
2948 return SOCKET_ERROR;
2949 }
2950 Socket->SharedData->ReuseAddresses = (*optval != 0) ? 1 : 0;
2951 return NO_ERROR;
2952
2954 if (optlen < sizeof(BOOL))
2955 {
2956 if (lpErrno) *lpErrno = WSAEFAULT;
2957 return SOCKET_ERROR;
2958 }
2959 Socket->SharedData->ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
2960 return NO_ERROR;
2961
2962 case SO_LINGER:
2963 if (optlen < sizeof(struct linger))
2964 {
2965 if (lpErrno) *lpErrno = WSAEFAULT;
2966 return SOCKET_ERROR;
2967 }
2969 optval,
2970 sizeof(struct linger));
2971 return NO_ERROR;
2972
2973 case SO_SNDBUF:
2974 if (optlen < sizeof(ULONG))
2975 {
2976 if (lpErrno) *lpErrno = WSAEFAULT;
2977 return SOCKET_ERROR;
2978 }
2979
2980 SetSocketInformation(Socket,
2982 NULL,
2983 (PULONG)optval,
2984 NULL,
2985 NULL,
2986 NULL);
2987 GetSocketInformation(Socket,
2989 NULL,
2990 &Socket->SharedData->SizeOfSendBuffer,
2991 NULL,
2992 NULL,
2993 NULL);
2994
2995 return NO_ERROR;
2996
2997 case SO_RCVBUF:
2998 if (optlen < sizeof(ULONG))
2999 {
3000 if (lpErrno) *lpErrno = WSAEFAULT;
3001 return SOCKET_ERROR;
3002 }
3003
3004 /* FIXME: We should not have to limit the packet receive buffer size like this. workaround for CORE-15804 */
3005 if (*(PULONG)optval > 0x2000)
3006 *(PULONG)optval = 0x2000;
3007
3008 SetSocketInformation(Socket,
3010 NULL,
3011 (PULONG)optval,
3012 NULL,
3013 NULL,
3014 NULL);
3015 GetSocketInformation(Socket,
3017 NULL,
3018 &Socket->SharedData->SizeOfRecvBuffer,
3019 NULL,
3020 NULL,
3021 NULL);
3022
3023 return NO_ERROR;
3024
3025 case SO_ERROR:
3026 if (optlen < sizeof(INT))
3027 {
3028 if (lpErrno) *lpErrno = WSAEFAULT;
3029 return SOCKET_ERROR;
3030 }
3031
3033 optval,
3034 sizeof(INT));
3035 return NO_ERROR;
3036
3037 case SO_SNDTIMEO:
3038 if (optlen < sizeof(DWORD))
3039 {
3040 if (lpErrno) *lpErrno = WSAEFAULT;
3041 return SOCKET_ERROR;
3042 }
3043
3045 optval,
3046 sizeof(DWORD));
3047 return NO_ERROR;
3048
3049 case SO_RCVTIMEO:
3050 if (optlen < sizeof(DWORD))
3051 {
3052 if (lpErrno) *lpErrno = WSAEFAULT;
3053 return SOCKET_ERROR;
3054 }
3055
3057 optval,
3058 sizeof(DWORD));
3059 return NO_ERROR;
3060
3061 case SO_KEEPALIVE:
3062 case SO_DONTROUTE:
3063 /* These go directly to the helper dll */
3064 goto SendToHelper;
3065
3066 default:
3067 /* Obviously this is a hack */
3068 ERR("MSAFD: Set unknown optname %x\n", optname);
3069 return NO_ERROR;
3070 }
3071 }
3072
3073SendToHelper:
3074 Errno = Socket->HelperData->WSHSetSocketInformation(Socket->HelperContext,
3075 s,
3076 Socket->TdiAddressHandle,
3077 Socket->TdiConnectionHandle,
3078 level,
3079 optname,
3080 (PCHAR)optval,
3081 optlen);
3082 if (lpErrno) *lpErrno = Errno;
3083 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
3084}
3085
3086/*
3087 * FUNCTION: Initialize service provider for a client
3088 * ARGUMENTS:
3089 * wVersionRequested = Highest WinSock SPI version that the caller can use
3090 * lpWSPData = Address of WSPDATA structure to initialize
3091 * lpProtocolInfo = Pointer to structure that defines the desired protocol
3092 * UpcallTable = Pointer to upcall table of the WinSock DLL
3093 * lpProcTable = Address of procedure table to initialize
3094 * RETURNS:
3095 * Status of operation
3096 */
3098int
3099WSPAPI
3101 _In_ WORD wVersionRequested,
3102 _In_ LPWSPDATA lpWSPData,
3103 _In_ LPWSAPROTOCOL_INFOW lpProtocolInfo,
3104 _In_ WSPUPCALLTABLE UpcallTable,
3105 _Out_ LPWSPPROC_TABLE lpProcTable)
3106{
3108
3109 if (((LOBYTE(wVersionRequested) == 2) && (HIBYTE(wVersionRequested) < 2)) ||
3110 (LOBYTE(wVersionRequested) < 2))
3111 {
3112 ERR("WSPStartup NOT SUPPORTED for version 0x%X\n", wVersionRequested);
3113 return WSAVERNOTSUPPORTED;
3114 }
3115 else
3116 Status = NO_ERROR;
3117 /* FIXME: Enable all cases of WSPStartup status */
3118 Upcalls = UpcallTable;
3119
3120 if (Status == NO_ERROR)
3121 {
3122 lpProcTable->lpWSPAccept = WSPAccept;
3123 lpProcTable->lpWSPAddressToString = WSPAddressToString;
3124 lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;
3125 lpProcTable->lpWSPBind = WSPBind;
3126 lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;
3127 lpProcTable->lpWSPCleanup = WSPCleanup;
3128 lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
3129 lpProcTable->lpWSPConnect = WSPConnect;
3130 lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;
3131 lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;
3132 lpProcTable->lpWSPEventSelect = WSPEventSelect;
3133 lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;
3134 lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
3135 lpProcTable->lpWSPGetSockName = WSPGetSockName;
3136 lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;
3137 lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;
3138 lpProcTable->lpWSPIoctl = WSPIoctl;
3139 lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf;
3140 lpProcTable->lpWSPListen = WSPListen;
3141 lpProcTable->lpWSPRecv = WSPRecv;
3142 lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;
3143 lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
3144 lpProcTable->lpWSPSelect = WSPSelect;
3145 lpProcTable->lpWSPSend = WSPSend;
3146 lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;
3147 lpProcTable->lpWSPSendTo = WSPSendTo;
3148 lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
3149 lpProcTable->lpWSPShutdown = WSPShutdown;
3150 lpProcTable->lpWSPSocket = WSPSocket;
3151 lpProcTable->lpWSPStringToAddress = WSPStringToAddress;
3152 lpWSPData->wVersion = MAKEWORD(2, 2);
3153 lpWSPData->wHighVersion = MAKEWORD(2, 2);
3154 /* Save CatalogEntryId for all upcalls */
3155 CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
3156 }
3157
3158 TRACE("Status (%d).\n", Status);
3159 return Status;
3160}
3161
3162
3163INT
3164WSPAPI
3166 IN DWORD dwAddressLength,
3167 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
3168 OUT LPWSTR lpszAddressString,
3169 IN OUT LPDWORD lpdwAddressStringLength,
3170 OUT LPINT lpErrno)
3171{
3172 SIZE_T size;
3173 WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
3174 WCHAR *p;
3175
3176 if (!lpsaAddress || !lpszAddressString || !lpdwAddressStringLength)
3177 {
3178 if (lpErrno) *lpErrno = WSAEFAULT;
3179 return SOCKET_ERROR;
3180 }
3181
3182 switch (lpsaAddress->sa_family)
3183 {
3184 case AF_INET:
3185 if (dwAddressLength < sizeof(SOCKADDR_IN))
3186 {
3187 if (lpErrno) *lpErrno = WSAEINVAL;
3188 return SOCKET_ERROR;
3189 }
3191 L"%u.%u.%u.%u:%u",
3192 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 24 & 0xff),
3193 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 16 & 0xff),
3194 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 8 & 0xff),
3195 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) & 0xff),
3196 ntohs(((SOCKADDR_IN *)lpsaAddress)->sin_port));
3197
3198 p = wcschr(buffer, L':');
3199 if (!((SOCKADDR_IN *)lpsaAddress)->sin_port)
3200 {
3201 *p = 0;
3202 }
3203 break;
3204 default:
3205 if (lpErrno) *lpErrno = WSAEINVAL;
3206 return SOCKET_ERROR;
3207 }
3208
3209 size = wcslen(buffer) + 1;
3210
3211 if (*lpdwAddressStringLength < size)
3212 {
3213 *lpdwAddressStringLength = size;
3214 if (lpErrno) *lpErrno = WSAEFAULT;
3215 return SOCKET_ERROR;
3216 }
3217
3218 *lpdwAddressStringLength = size;
3219 wcscpy(lpszAddressString, buffer);
3220 return 0;
3221}
3222
3223INT
3224WSPAPI
3227 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
3228 OUT LPSOCKADDR lpAddress,
3229 IN OUT LPINT lpAddressLength,
3230 OUT LPINT lpErrno)
3231{
3232 int numdots = 0;
3233 USHORT port;
3234 LONG inetaddr = 0, ip_part;
3235 LPWSTR *bp = NULL;
3237
3238 if (!lpAddressLength || !lpAddress || !AddressString)
3239 {
3240 if (lpErrno) *lpErrno = WSAEINVAL;
3241 return SOCKET_ERROR;
3242 }
3243
3244 sockaddr = (SOCKADDR_IN *)lpAddress;
3245
3246 /* Set right address family */
3247 if (lpProtocolInfo != NULL)
3248 {
3249 sockaddr->sin_family = lpProtocolInfo->iAddressFamily;
3250 }
3251 else
3252 {
3253 sockaddr->sin_family = AddressFamily;
3254 }
3255
3256 /* Report size */
3257 if (AddressFamily == AF_INET)
3258 {
3259 if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN))
3260 {
3261 if (lpErrno) *lpErrno = WSAEFAULT;
3262 }
3263 else
3264 {
3265 // translate ip string to ip
3266
3267 /* Get ip number */
3268 bp = &AddressString;
3269 inetaddr = 0;
3270
3271 while (*bp < &AddressString[wcslen(AddressString)])
3272 {
3273 ip_part = wcstol(*bp, bp, 10);
3274 /* ip part number should be in range 0-255 */
3275 if (ip_part < 0 || ip_part > 255)
3276 {
3277 if (lpErrno) *lpErrno = WSAEINVAL;
3278 return SOCKET_ERROR;
3279 }
3280 inetaddr = (inetaddr << 8) + ip_part;
3281 /* we end on string end or port separator */
3282 if ((*bp)[0] == 0 || (*bp)[0] == L':')
3283 break;
3284 /* ip parts are dot separated. verify it */
3285 if ((*bp)[0] != L'.')
3286 {
3287 if (lpErrno) *lpErrno = WSAEINVAL;
3288 return SOCKET_ERROR;
3289 }
3290 /* count the dots */
3291 numdots++;
3292 /* move over the dot to next ip part */
3293 (*bp)++;
3294 }
3295
3296 /* check dots count */
3297 if (numdots != 3)
3298 {
3299 if (lpErrno) *lpErrno = WSAEINVAL;
3300 return SOCKET_ERROR;
3301 }
3302
3303 /* Get port number */
3304 if ((*bp)[0] == L':')
3305 {
3306 /* move over the column to port part */
3307 (*bp)++;
3308 /* next char should be numeric */
3309 if ((*bp)[0] < L'0' || (*bp)[0] > L'9')
3310 {
3311 if (lpErrno) *lpErrno = WSAEINVAL;
3312 return SOCKET_ERROR;
3313 }
3314 port = wcstol(*bp, bp, 10);
3315 }
3316 else
3317 {
3318 port = 0;
3319 }
3320
3321 if (lpErrno) *lpErrno = NO_ERROR;
3322 /* rest sockaddr.sin_addr.s_addr
3323 for we need to be sure it is zero when we come to while */
3324 *lpAddressLength = sizeof(*sockaddr);
3325 memset(lpAddress, 0, sizeof(*sockaddr));
3326 sockaddr->sin_family = AF_INET;
3327 sockaddr->sin_addr.s_addr = inetaddr;
3328 sockaddr->sin_port = port;
3329 }
3330 }
3331
3332 if (lpErrno && !*lpErrno)
3333 {
3334 return 0;
3335 }
3336
3337 return SOCKET_ERROR;
3338}
3339
3340/*
3341 * FUNCTION: Cleans up service provider for a client
3342 * ARGUMENTS:
3343 * lpErrno = Address of buffer for error information
3344 * RETURNS:
3345 * 0 if successful, or SOCKET_ERROR if not
3346 */
3347INT
3348WSPAPI
3350
3351{
3352 TRACE("Leaving.\n");
3353
3354 if (lpErrno) *lpErrno = NO_ERROR;
3355
3356 return 0;
3357}
3358
3359static
3360VOID
3361NTAPI
3366{
3368
3369 TRACE("MsafdInfoAPC(%p %lx %lx)\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information);
3370
3371 if (Context->lpCompletionRoutine)
3372 Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
3373
3374 /* Free IOCTL buffer */
3375 HeapFree(GlobalHeap, 0, Context->lpInfoData);
3376
3378}
3379
3380int
3382 ULONG AfdInformationClass,
3383 PBOOLEAN Boolean OPTIONAL,
3385 PLARGE_INTEGER LargeInteger OPTIONAL,
3386 LPWSAOVERLAPPED Overlapped OPTIONAL,
3388{
3389 PIO_STATUS_BLOCK IOSB;
3390 IO_STATUS_BLOCK DummyIOSB;
3391 PAFD_INFO InfoData;
3393 PMSAFD_INFO_APC_CONTEXT APCContext;
3394 PIO_APC_ROUTINE APCFunction;
3395 HANDLE Event = NULL;
3397
3398 InfoData = HeapAlloc(GlobalHeap, 0, sizeof(*InfoData));
3399 if (!InfoData)
3400 return SOCKET_ERROR;
3401
3404 NULL,
3406 FALSE);
3407 if (!NT_SUCCESS(Status))
3408 {
3409 HeapFree(GlobalHeap, 0, InfoData);
3410 return SOCKET_ERROR;
3411 }
3412
3413 /* Set Info Class */
3414 InfoData->InformationClass = AfdInformationClass;
3415
3416 /* Verify if we should use APC */
3417 if (!Overlapped)
3418 {
3419 /* Not using Overlapped structure, so use normal blocking on event */
3420 APCContext = NULL;
3421 APCFunction = NULL;
3422 Event = SockEvent;
3423 IOSB = &DummyIOSB;
3424 }
3425 else
3426 {
3427 /* Overlapped request for non overlapped opened socket */
3428 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3429 {
3430 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3432 HeapFree(GlobalHeap, 0, InfoData);
3434 }
3435
3436 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
3437 if (!APCContext)
3438 {
3439 ERR("Not enough memory for APC Context\n");
3441 HeapFree(GlobalHeap, 0, InfoData);
3443 }
3445 APCContext->lpOverlapped = Overlapped;
3446 APCContext->lpInfoData = InfoData;
3447 APCFunction = &MsafdInfoAPC;
3448
3449 if (!CompletionRoutine)
3450 Event = Overlapped->hEvent;
3451
3452 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3453 }
3454
3455 IOSB->Status = STATUS_PENDING;
3456
3457 /* Send IOCTL */
3459 Event,
3460 APCFunction,
3461 APCContext,
3462 IOSB,
3464 InfoData,
3465 sizeof(*InfoData),
3466 InfoData,
3467 sizeof(*InfoData));
3468
3469 /* Wait for completion if not overlapped */
3470 if (!Overlapped && Status == STATUS_PENDING)
3471 {
3473 Status = IOSB->Status;
3474 }
3475
3476 TRACE("Status %lx\n", Status);
3477
3478 if (Status == STATUS_SUCCESS)
3479 {
3480 /* Return Information */
3481 if (Ulong != NULL)
3482 {
3483 *Ulong = InfoData->Information.Ulong;
3484 }
3485 if (LargeInteger != NULL)
3486 {
3487 *LargeInteger = InfoData->Information.LargeInteger;
3488 }
3489 if (Boolean != NULL)
3490 {
3491 *Boolean = InfoData->Information.Boolean;
3492 }
3493 }
3494
3496 if (!APCFunction)
3497 {
3498 /* When using APC, this will be freed by the APC function */
3499 HeapFree(GlobalHeap, 0, InfoData);
3500 }
3501
3502 return MsafdReturnWithErrno(Status, NULL, 0, NULL);
3503}
3504
3505
3506int
3508 ULONG AfdInformationClass,
3509 PBOOLEAN Boolean OPTIONAL,
3511 PLARGE_INTEGER LargeInteger OPTIONAL,
3512 LPWSAOVERLAPPED Overlapped OPTIONAL,
3514{
3515 PIO_STATUS_BLOCK IOSB;
3516 IO_STATUS_BLOCK DummyIOSB;
3517 PAFD_INFO InfoData;
3519 PMSAFD_INFO_APC_CONTEXT APCContext;
3520 PIO_APC_ROUTINE APCFunction;
3521 HANDLE Event = NULL;
3523
3524 InfoData = HeapAlloc(GlobalHeap, 0, sizeof(*InfoData));
3525 if (!InfoData)
3526 return SOCKET_ERROR;
3527
3530 NULL,
3532 FALSE);
3533 if (!NT_SUCCESS(Status))
3534 {
3535 HeapFree(GlobalHeap, 0, InfoData);
3536 return SOCKET_ERROR;
3537 }
3538
3539 /* Set Info Class */
3540 InfoData->InformationClass = AfdInformationClass;
3541
3542 /* Set Information */
3543 if (Ulong != NULL)
3544 {
3545 InfoData->Information.Ulong = *Ulong;
3546 }
3547 if (LargeInteger != NULL)
3548 {
3549 InfoData->Information.LargeInteger = *LargeInteger;
3550 }
3551 if (Boolean != NULL)
3552 {
3553 InfoData->Information.Boolean = *Boolean;
3554 }
3555
3556 /* Verify if we should use APC */
3557 if (!Overlapped)
3558 {
3559 /* Not using Overlapped structure, so use normal blocking on event */
3560 APCContext = NULL;
3561 APCFunction = NULL;
3562 Event = SockEvent;
3563 IOSB = &DummyIOSB;
3564 }
3565 else
3566 {
3567 /* Overlapped request for non overlapped opened socket */
3568 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3569 {
3570 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3572 HeapFree(GlobalHeap, 0, InfoData);
3574 }
3575
3576 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
3577 if (!APCContext)
3578 {
3579 ERR("Not enough memory for APC Context\n");
3581 HeapFree(GlobalHeap, 0, InfoData);
3583 }
3585 APCContext->lpOverlapped = Overlapped;
3586 APCContext->lpInfoData = InfoData;
3587 APCFunction = &MsafdInfoAPC;
3588
3589 if (!CompletionRoutine)
3590 Event = Overlapped->hEvent;
3591
3592 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3593 }
3594
3595 IOSB->Status = STATUS_PENDING;
3596
3597 /* Send IOCTL */
3599 Event,
3600 APCFunction,
3601 APCContext,
3602 IOSB,
3604 InfoData,
3605 sizeof(*InfoData),
3606 NULL,
3607 0);
3608
3609 /* Wait for completion if not overlapped */
3610 if (!Overlapped && Status == STATUS_PENDING)
3611 {
3613 Status = IOSB->Status;
3614 }
3615
3616 TRACE("Status %lx\n", Status);
3617
3619 if (!APCFunction)
3620 {
3621 /* When using APC, this will be freed by the APC function */
3622 HeapFree(GlobalHeap, 0, InfoData);
3623 }
3624
3625 return MsafdReturnWithErrno(Status, NULL, 0, NULL);
3626}
3627
3630{
3631 PSOCKET_INFORMATION CurrentSocket;
3632
3634
3635 CurrentSocket = SocketListHead;
3636 while (CurrentSocket)
3637 {
3638 if (CurrentSocket->Handle == Handle)
3639 {
3641 return CurrentSocket;
3642 }
3643
3644 CurrentSocket = CurrentSocket->NextSocket;
3645 }
3646
3648
3649 return NULL;
3650}
3651
3653{
3654 IO_STATUS_BLOCK IOSB;
3655 SOCKET_CONTEXT ContextData;
3658
3661 NULL,
3663 FALSE);
3664
3665 if( !NT_SUCCESS(Status) )
3666 return SOCKET_ERROR;
3667
3668 /* Create Context */
3669 ContextData.SharedData = *Socket->SharedData;
3670 ContextData.SizeOfHelperData = 0;
3671 RtlCopyMemory (&ContextData.LocalAddress,
3672 Socket->LocalAddress,
3674 RtlCopyMemory (&ContextData.RemoteAddress,
3675 Socket->RemoteAddress,
3677
3678 /* Send IOCTL */
3680 SockEvent,
3681 NULL,
3682 NULL,
3683 &IOSB,
3685 &ContextData,
3686 sizeof(ContextData),
3687 NULL,
3688 0);
3689
3690 /* Wait for Completion */
3691 if (Status == STATUS_PENDING)
3692 {
3694 Status = IOSB.Status;
3695 }
3696
3697 NtClose( SockEvent );
3698
3700}
3701
3703{
3704 HANDLE hAsyncThread;
3705 DWORD AsyncThreadId;
3706 HANDLE AsyncEvent;
3709
3710 /* Check if the Thread Already Exists */
3712 {
3714 return TRUE;
3715 }
3716
3717 /* Create the Completion Port */
3719 {
3722 NULL,
3723 2); // Allow 2 threads only
3724 if (!NT_SUCCESS(Status))
3725 {
3726 ERR("Failed to create completion port: 0x%08x\n", Status);
3727 return FALSE;
3728 }
3729 /* Protect Handle */
3730 HandleFlags.ProtectFromClose = TRUE;
3731 HandleFlags.Inherit = FALSE;
3734 &HandleFlags,
3735 sizeof(HandleFlags));
3736 }
3737
3738 /* Create the Async Event */
3739 Status = NtCreateEvent(&AsyncEvent,
3741 NULL,
3743 FALSE);
3744
3745 /* Create the Async Thread */
3746 hAsyncThread = CreateThread(NULL,
3747 0,
3749 NULL,
3750 0,
3751 &AsyncThreadId);
3752
3753 /* Close the Handle */
3754 NtClose(hAsyncThread);
3755
3756 /* Increase the Reference Count */
3758 return TRUE;
3759}
3760
3761ULONG
3762NTAPI
3764{
3765 PVOID AsyncContext;
3766 PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine;
3767 IO_STATUS_BLOCK IOSB;
3769
3770 /* Make the Thread Higher Priority */
3772
3773 /* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */
3774 do
3775 {
3777 (PVOID*)&AsyncCompletionRoutine,
3778 &AsyncContext,
3779 &IOSB,
3780 NULL);
3781 /* Call the Async Function */
3782 if (NT_SUCCESS(Status))
3783 {
3784 (*AsyncCompletionRoutine)(AsyncContext, &IOSB);
3785 }
3786 else
3787 {
3788 /* It Failed, sleep for a second */
3789 Sleep(1000);
3790 }
3791 } while ((Status != STATUS_TIMEOUT));
3792
3793 /* The Thread has Ended */
3794 return 0;
3795}
3796
3798{
3799 UNICODE_STRING AfdHelper;
3801 IO_STATUS_BLOCK IoSb;
3802 FILE_COMPLETION_INFORMATION CompletionInfo;
3804
3805 /* First, make sure we're not already initialized */
3807 {
3808 return TRUE;
3809 }
3810
3811 /* Set up Handle Name and Object */
3812 RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" );
3814 &AfdHelper,
3816 NULL,
3817 NULL);
3818
3819 /* Open the Handle to AFD */
3823 &IoSb,
3824 NULL,
3825 0,
3828 0,
3829 NULL,
3830 0);
3831
3832 /*
3833 * Now Set up the Completion Port Information
3834 * This means that whenever a Poll is finished, the routine will be executed
3835 */
3836 CompletionInfo.Port = SockAsyncCompletionPort;
3837 CompletionInfo.Key = SockAsyncSelectCompletionRoutine;
3839 &IoSb,
3840 &CompletionInfo,
3841 sizeof(CompletionInfo),
3843
3844
3845 /* Protect the Handle */
3846 HandleFlags.ProtectFromClose = TRUE;
3847 HandleFlags.Inherit = FALSE;
3850 &HandleFlags,
3851 sizeof(HandleFlags));
3852
3853
3854 /* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */
3856 return TRUE;
3857}
3858
3860{
3861
3862 PASYNC_DATA AsyncData = Context;
3863 PSOCKET_INFORMATION Socket;
3864 ULONG x;
3865
3866 /* Get the Socket */
3867 Socket = AsyncData->ParentSocket;
3868
3869 /* Check if the Sequence Number Changed behind our back */
3870 if (AsyncData->SequenceNumber != Socket->SharedData->SequenceNumber )
3871 {
3872 return;
3873 }
3874
3875 /* Check we were manually called b/c of a failure */
3877 {
3878 /* FIXME: Perform Upcall */
3879 return;
3880 }
3881
3882 for (x = 1; x; x<<=1)
3883 {
3884 switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x)
3885 {
3886 case AFD_EVENT_RECEIVE:
3887 if (0 != (Socket->SharedData->AsyncEvents & FD_READ) &&
3888 0 == (Socket->SharedData->AsyncDisabledEvents & FD_READ))
3889 {
3890 /* Make the Notification */
3892 Socket->SharedData->wMsg,
3893 Socket->Handle,
3895 /* Disable this event until the next read(); */
3897 }
3898 break;
3899
3901 if (0 != (Socket->SharedData->AsyncEvents & FD_OOB) &&
3902 0 == (Socket->SharedData->AsyncDisabledEvents & FD_OOB))
3903 {
3904 /* Make the Notification */
3906 Socket->SharedData->wMsg,
3907 Socket->Handle,
3909 /* Disable this event until the next read(); */
3911 }
3912 break;
3913
3914 case AFD_EVENT_SEND:
3915 if (0 != (Socket->SharedData->AsyncEvents & FD_WRITE) &&
3916 0 == (Socket->SharedData->AsyncDisabledEvents & FD_WRITE))
3917 {
3918 /* Make the Notification */
3920 Socket->SharedData->wMsg,
3921 Socket->Handle,
3923 /* Disable this event until the next write(); */
3925 }
3926 break;
3927
3928 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
3929 case AFD_EVENT_CONNECT:
3931 if (0 != (Socket->SharedData->AsyncEvents & FD_CONNECT) &&
3932 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CONNECT))
3933 {
3934 /* Make the Notification */
3936 Socket->SharedData->wMsg,
3937 Socket->Handle,
3939 /* Disable this event forever; */
3941 }
3942 break;
3943
3944 case AFD_EVENT_ACCEPT:
3945 if (0 != (Socket->SharedData->AsyncEvents & FD_ACCEPT) &&
3946 0 == (Socket->SharedData->AsyncDisabledEvents & FD_ACCEPT))
3947 {
3948 /* Make the Notification */
3950 Socket->SharedData->wMsg,
3951 Socket->Handle,
3953 /* Disable this event until the next accept(); */
3955 }
3956 break;
3957
3959 case AFD_EVENT_ABORT:
3960 case AFD_EVENT_CLOSE:
3961 if (0 != (Socket->SharedData->AsyncEvents & FD_CLOSE) &&
3962 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CLOSE))
3963 {
3964 /* Make the Notification */
3966 Socket->SharedData->wMsg,
3967 Socket->Handle,
3969 /* Disable this event forever; */
3971 }
3972 break;
3973 /* FIXME: Support QOS */
3974 }
3975 }
3976
3977 /* Check if there are any events left for us to check */
3978 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
3979 {
3980 return;
3981 }
3982
3983 /* Keep Polling */
3984 SockProcessAsyncSelect(Socket, AsyncData);
3985 return;
3986}
3987
3989{
3990
3991 ULONG lNetworkEvents;
3993
3994 /* Set up the Async Data Event Info */
3995 AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF;
3996 AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF;
3997 AsyncData->AsyncSelectInfo.HandleCount = 1;
3998 AsyncData->AsyncSelectInfo.Exclusive = TRUE;
3999 AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle;
4000 AsyncData->AsyncSelectInfo.Handles[0].Events = 0;
4001
4002 /* Remove unwanted events */
4003 lNetworkEvents = Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents);
4004
4005 /* Set Events to wait for */
4006 if (lNetworkEvents & FD_READ)
4007 {
4009 }
4010
4011 if (lNetworkEvents & FD_WRITE)
4012 {
4014 }
4015
4016 if (lNetworkEvents & FD_OOB)
4017 {
4019 }
4020
4021 if (lNetworkEvents & FD_ACCEPT)
4022 {
4024 }
4025
4026 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
4027 if (lNetworkEvents & FD_CONNECT)
4028 {
4030 }
4031
4032 if (lNetworkEvents & FD_CLOSE)
4033 {
4035 }
4036
4037 if (lNetworkEvents & FD_QOS)
4038 {
4040 }
4041
4042 if (lNetworkEvents & FD_GROUP_QOS)
4043 {
4045 }
4046
4047 /* Send IOCTL */
4049 NULL,
4050 NULL,
4051 AsyncData,
4052 &AsyncData->IoStatusBlock,
4054 &AsyncData->AsyncSelectInfo,
4055 sizeof(AsyncData->AsyncSelectInfo),
4056 &AsyncData->AsyncSelectInfo,
4057 sizeof(AsyncData->AsyncSelectInfo));
4058
4059 /* I/O Manager Won't call the completion routine, let's do it manually */
4060 if (NT_SUCCESS(Status))
4061 {
4062 return;
4063 }
4064 else
4065 {
4066 AsyncData->IoStatusBlock.Status = Status;
4067 SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock);
4068 }
4069}
4070
4072{
4073 PASYNC_DATA AsyncData = Context;
4074 BOOL FreeContext = TRUE;
4075 PSOCKET_INFORMATION Socket;
4076
4077 /* Get the Socket */
4078 Socket = AsyncData->ParentSocket;
4079
4080 /* If someone closed it, stop the function */
4081 if (Socket->SharedData->State != SocketClosed)
4082 {
4083 /* Check if the Sequence Number changed by now, in which case quit */
4084 if (AsyncData->SequenceNumber == Socket->SharedData->SequenceNumber)
4085 {
4086 /* Do the actual select, if needed */
4087 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)))
4088 {
4089 SockProcessAsyncSelect(Socket, AsyncData);
4090 FreeContext = FALSE;
4091 }
4092 }
4093 }
4094
4095 /* Free the Context */
4096 if (FreeContext)
4097 {
4098 HeapFree(GetProcessHeap(), 0, AsyncData);
4099 }
4100
4101 return;
4102}
4103
4104VOID
4106 IN ULONG Event)
4107{
4108 PASYNC_DATA AsyncData;
4109
4110 /* Make sure the event is actually disabled */
4111 if (!(Socket->SharedData->AsyncDisabledEvents & Event))
4112 {
4113 return;
4114 }
4115
4116 /* Re-enable it */
4117 Socket->SharedData->AsyncDisabledEvents &= ~Event;
4118
4119 /* Return if no more events are being polled */
4120 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
4121 {
4122 return;
4123 }
4124
4125 /* Wait on new events */
4126 AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(ASYNC_DATA));
4127 if (!AsyncData) return;
4128
4129 /* Create the Asynch Thread if Needed */
4131
4132 /* Increase the sequence number to stop anything else */
4133 Socket->SharedData->SequenceNumber++;
4134
4135 /* Set up the Async Data */
4136 AsyncData->ParentSocket = Socket;
4137 AsyncData->SequenceNumber = Socket->SharedData->SequenceNumber;
4138
4139 /* Begin Async Select by using I/O Completion */
4142 AsyncData,
4143 0,
4144 0);
4145
4146 /* All done */
4147 return;
4148}
4149
4150BOOL
4151WINAPI
4155{
4156
4157 switch (dwReason)
4158 {
4159 case DLL_PROCESS_ATTACH:
4160
4161 TRACE("Loading MSAFD.DLL \n");
4162
4163 /* Don't need thread attach notifications
4164 so disable them to improve performance */
4165 DisableThreadLibraryCalls(hInstDll);
4166
4167 /* List of DLL Helpers */
4169
4170 /* Heap to use when allocating */
4172
4173 /* Initialize the lock that protects our socket list */
4175
4176 TRACE("MSAFD.DLL has been loaded\n");
4177
4178 break;
4179
4180 case DLL_THREAD_ATTACH:
4181 break;
4182
4183 case DLL_THREAD_DETACH:
4184 break;
4185
4186 case DLL_PROCESS_DETACH:
4187
4188 /* Delete the socket list lock */
4190
4191 break;
4192 }
4193
4194 TRACE("DllMain of msafd.dll (leaving)\n");
4195
4196 return TRUE;
4197}
4198
4199/* EOF */
unsigned char BOOLEAN
#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
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 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 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:1227
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:3362
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:3165
int WSPAPI WSPListen(SOCKET Handle, int Backlog, LPINT lpErrno)
Definition: dllmain.c:995
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:2887
VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:3859
INT WSPAPI WSPCleanup(OUT LPINT lpErrno)
Definition: dllmain.c:3349
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:3381
int WSPAPI WSPConnect(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
Definition: dllmain.c:1898
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:2711
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:3702
VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
Definition: dllmain.c:3988
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:1431
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3629
INT WSPAPI WSPGetPeerName(IN SOCKET s, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
Definition: dllmain.c:2360
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:1079
int CreateContext(PSOCKET_INFORMATION Socket)
Definition: dllmain.c:3652
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:4071
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:3507
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:3763
int WSPAPI WSPShutdown(SOCKET Handle, int HowTo, LPINT lpErrno)
Definition: dllmain.c:2178
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:3225
_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:3100
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:2463
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:1448
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:1845
INT WSPAPI WSPGetSockName(IN SOCKET Handle, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
Definition: dllmain.c:2258
BOOLEAN SockAsyncSelectCalled
Definition: dllmain.c:29
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:4105
WSPUPCALLTABLE Upcalls
Definition: dllmain.c:20
BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID)
Definition: dllmain.c:3797
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 WSPConnectEx(IN SOCKET s, IN const struct sockaddr *name, IN int namelen, IN PVOID lpSendBuffer, IN DWORD dwSendDataLength, OUT LPDWORD lpdwBytesSent, IN OUT LPOVERLAPPED lpOverlapped)
Definition: stubs.c:75
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:104
BOOL WSPAPI WSPDisconnectEx(IN SOCKET hSocket, IN LPOVERLAPPED lpOverlapped, IN DWORD dwFlags, IN DWORD reserved)
Definition: stubs.c:91
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:568
enum _SOCKET_STATE SOCKET_STATE
HANDLE SockEvent
@ SocketBound
Definition: msafd.h:47
@ SocketConnected
Definition: msafd.h:49
@ SocketClosed
Definition: msafd.h:50
@ SocketOpen
Definition: msafd.h:46
VOID(* PASYNC_COMPLETION_ROUTINE)(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: msafd.h:564
_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
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_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 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:186
#define AFD_EVENT_ACCEPT
Definition: shared.h:210
#define AFD_INFO_RECEIVE_WINDOW_SIZE
Definition: shared.h:185
struct _AFD_POLL_INFO * PAFD_POLL_INFO
#define AFD_DISCONNECT_RECV
Definition: shared.h:198
struct _AFD_CREATE_PACKET * PAFD_CREATE_PACKET
#define IOCTL_AFD_SET_INFO
Definition: shared.h:295
struct _AFD_CONNECT_INFO * PAFD_CONNECT_INFO
#define AFD_EVENT_SEND
Definition: shared.h:205
#define AfdCommand
Definition: shared.h:12
#define AFD_INFO_RECEIVE_CONTENT_SIZE
Definition: shared.h:188
#define IOCTL_AFD_WAIT_FOR_LISTEN
Definition: shared.h:273
#define AFD_PACKET_COMMAND_LENGTH
Definition: shared.h:11
#define IOCTL_AFD_GET_SOCK_NAME
Definition: shared.h:289
#define IOCTL_AFD_DEFER_ACCEPT
Definition: shared.h:331
#define IOCTL_AFD_START_LISTEN
Definition: shared.h:271
#define AFD_EVENT_OOB_RECEIVE
Definition: shared.h:204
#define AFD_EVENT_CONNECT_FAIL
Definition: shared.h:211
#define AFD_EVENT_RECEIVE
Definition: shared.h:203
struct _AFD_RECEIVED_ACCEPT_DATA * PAFD_RECEIVED_ACCEPT_DATA
#define AFD_ENDPOINT_RAW
Definition: shared.h:155
struct _AFD_HANDLE_ AFD_HANDLE
#define IOCTL_AFD_SELECT
Definition: shared.h:285
#define AFD_DISCONNECT_ABORT
Definition: shared.h:199
#define AFD_EVENT_DISCONNECT
Definition: shared.h:206
#define AFD_ENDPOINT_D_ROOT
Definition: shared.h:158
#define AFD_INFO_BLOCKING_MODE
Definition: shared.h:183
#define AFD_ENDPOINT_MULTIPOINT
Definition: shared.h:156
#define IOCTL_AFD_GET_INFO
Definition: shared.h:327
#define IOCTL_AFD_SET_CONNECT_DATA
Definition: shared.h:303
#define IOCTL_AFD_CONNECT
Definition: shared.h:269
#define IOCTL_AFD_ACCEPT
Definition: shared.h:275
#define IOCTL_AFD_BIND
Definition: shared.h:267
#define IOCTL_AFD_DISCONNECT
Definition: shared.h:287
#define AFD_ENDPOINT_MESSAGE_ORIENTED
Definition: shared.h:154
struct _AFD_CREATE_PACKET AFD_CREATE_PACKET
#define AFD_EVENT_ABORT
Definition: shared.h:207
#define AFD_INFO_SENDS_IN_PROGRESS
Definition: shared.h:184
#define AFD_EVENT_QOS
Definition: shared.h:212
#define AFD_ENDPOINT_CONNECTIONLESS
Definition: shared.h:153
#define IOCTL_AFD_GET_PENDING_CONNECT_DATA
Definition: shared.h:333
#define AFD_EVENT_CLOSE
Definition: shared.h:208
#define AFD_EVENT_CONNECT
Definition: shared.h:209
#define AFD_EVENT_GROUP_QOS
Definition: shared.h:213
#define IOCTL_AFD_SET_CONNECT_DATA_SIZE
Definition: shared.h:319
#define IOCTL_AFD_GET_PEER_NAME
Definition: shared.h:291
#define IOCTL_AFD_SET_CONTEXT
Definition: shared.h:301
#define AFD_ENDPOINT_C_ROOT
Definition: shared.h:157
#define AFD_INFO_GROUP_ID_TYPE
Definition: shared.h:187
#define IOCTL_AFD_GET_CONNECT_DATA
Definition: shared.h:311
#define AFD_DISCONNECT_SEND
Definition: shared.h:197
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:137
ULONG DisconnectType
Definition: shared.h:136
SOCKET Handle
Definition: shared.h:50
ULONG Events
Definition: shared.h:51
union _AFD_INFO::@3615 Information
ULONG InformationClass
Definition: shared.h:29
ULONG Ulong
Definition: shared.h:31
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
AFD_POLL_INFO AsyncSelectInfo
Definition: msafd.h:133
DWORD SequenceNumber
Definition: msafd.h:131
PSOCKET_INFORMATION ParentSocket
Definition: msafd.h:130
IO_STATUS_BLOCK IoStatusBlock
Definition: msafd.h:132
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:161
PAFD_INFO lpInfoData
Definition: msafd.h:140
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
Definition: msafd.h:139
LPWSAOVERLAPPED lpOverlapped
Definition: msafd.h:138
SOCKADDR_ADDRESS_INFO AddressInfo
Definition: wsahelp.h:44
SOCKADDR_ENDPOINT_INFO EndpointInfo
Definition: wsahelp.h:45
SOCK_SHARED_INFO SharedData
Definition: msafd.h:121
SOCKADDR RemoteAddress
Definition: msafd.h:125
SOCKADDR LocalAddress
Definition: msafd.h:124
ULONG SizeOfHelperData
Definition: msafd.h:122
PVOID HelperContext
Definition: msafd.h:104
LONG NetworkEvents
Definition: msafd.h:111
HANDLE TdiConnectionHandle
Definition: msafd.h:108
struct _SOCKET_INFORMATION * NextSocket
Definition: msafd.h:116
HANDLE SharedDataHandle
Definition: msafd.h:101
PSOCKADDR LocalAddress
Definition: msafd.h:105
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:100
PHELPER_DATA HelperData
Definition: msafd.h:103
PSOCKADDR RemoteAddress
Definition: msafd.h:106
SOCKET Handle
Definition: msafd.h:99
HANDLE TdiAddressHandle
Definition: msafd.h:107
DWORD HelperEvents
Definition: msafd.h:102
WSAPROTOCOL_INFOW ProtocolInfo
Definition: msafd.h:115
DWORD GroupType
Definition: msafd.h:85
BOOLEAN Broadcast
Definition: msafd.h:69
BOOLEAN Debug
Definition: msafd.h:70
LONG AsyncDisabledEvents
Definition: msafd.h:93
INT SizeOfLocalAddress
Definition: msafd.h:59
ULONG RecvTimeout
Definition: msafd.h:63
BOOLEAN ExclusiveAddressUse
Definition: msafd.h:73
SOCKADDR WSRemoteAddress
Definition: msafd.h:95
BOOLEAN OobInline
Definition: msafd.h:71
SOCKET_STATE State
Definition: msafd.h:54
INT AddressFamily
Definition: msafd.h:56
ULONG SizeOfSendBuffer
Definition: msafd.h:65
BOOLEAN NonBlocking
Definition: msafd.h:74
BOOLEAN UseSAN
Definition: msafd.h:79
BOOLEAN SendShutdown
Definition: msafd.h:77
SOCKADDR WSLocalAddress
Definition: msafd.h:94
LONG RefCount
Definition: msafd.h:55
BOOLEAN ReuseAddresses
Definition: msafd.h:72
LONG AsyncEvents
Definition: msafd.h:92
ULONG SizeOfRecvBuffer
Definition: msafd.h:64
INT SocketLastError
Definition: msafd.h:87
struct linger LingerData
Definition: msafd.h:61
DWORD SequenceNumber
Definition: msafd.h:90
DWORD ProviderFlags
Definition: msafd.h:83
INT SizeOfRemoteAddress
Definition: msafd.h:60
BOOLEAN ReceiveShutdown
Definition: msafd.h:76
ULONG SendTimeout
Definition: msafd.h:62
INT SocketType
Definition: msafd.h:57
BOOLEAN Listening
Definition: msafd.h:68
BOOLEAN UseDelayedAcceptance
Definition: msafd.h:78
DWORD ServiceFlags1
Definition: msafd.h:82
GROUP GroupID
Definition: msafd.h:84
ULONG ConnectTime
Definition: msafd.h:66
DWORD CreateFlags
Definition: msafd.h:81
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:802
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
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:733
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:1148
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
_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