ReactOS 0.4.16-dev-251-ga17b6e9
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 ERR("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
451 IN DWORD dwProcessId,
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 }
469 if ( !(hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId)) )
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
613/*
614 * FUNCTION: Closes an open socket
615 * ARGUMENTS:
616 * s = Socket descriptor
617 * lpErrno = Address of buffer for error information
618 * RETURNS:
619 * NO_ERROR, or SOCKET_ERROR if the socket could not be closed
620 */
621INT
622WSPAPI
624 OUT LPINT lpErrno)
625{
627 PSOCKET_INFORMATION Socket = NULL, CurrentSocket;
630 AFD_DISCONNECT_INFO DisconnectInfo;
631 SOCKET_STATE OldState;
632 LONG LingerWait = -1;
633 DWORD References;
634
635 /* Get the Socket Structure associate to this Socket*/
636 Socket = GetSocketStructure(Handle);
637 if (!Socket)
638 {
639 if (lpErrno) *lpErrno = WSAENOTSOCK;
640 return SOCKET_ERROR;
641 }
642
643 /* Create the Wait Event */
646 NULL,
648 FALSE);
649
650 if(!NT_SUCCESS(Status))
651 {
652 ERR("NtCreateEvent failed: 0x%08x\n", Status);
653 return SOCKET_ERROR;
654 }
655
656 if (Socket->HelperEvents & WSH_NOTIFY_CLOSE)
657 {
658 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
659 Socket->Handle,
660 Socket->TdiAddressHandle,
661 Socket->TdiConnectionHandle,
663
664 if (Status)
665 {
666 if (lpErrno) *lpErrno = Status;
667 ERR("WSHNotify failed. Error 0x%#x\n", Status);
669 return SOCKET_ERROR;
670 }
671 }
672
673 /* If a Close is already in Process, give up */
674 if (Socket->SharedData->State == SocketClosed)
675 {
676 WARN("Socket is closing.\n");
678 if (lpErrno) *lpErrno = WSAENOTSOCK;
679 return SOCKET_ERROR;
680 }
681
682 /* Decrement reference count on SharedData */
683 References = InterlockedDecrement(&Socket->SharedData->RefCount);
684 if (References)
685 goto ok;
686
687 /* Set the state to close */
688 OldState = Socket->SharedData->State;
689 Socket->SharedData->State = SocketClosed;
690
691 /* If SO_LINGER is ON and the Socket is connected, we need to disconnect */
692 /* FIXME: Should we do this on Datagram Sockets too? */
693 if ((OldState == SocketConnected) && (Socket->SharedData->LingerData.l_onoff))
694 {
695 ULONG SendsInProgress;
696 ULONG SleepWait;
697
698 /* We need to respect the timeout */
699 SleepWait = 100;
700 LingerWait = Socket->SharedData->LingerData.l_linger * 1000;
701
702 /* Loop until no more sends are pending, within the timeout */
703 while (LingerWait)
704 {
705 /* Find out how many Sends are in Progress */
706 if (GetSocketInformation(Socket,
708 NULL,
709 &SendsInProgress,
710 NULL,
711 NULL,
712 NULL))
713 {
714 /* Bail out if anything but NO_ERROR */
715 LingerWait = 0;
716 break;
717 }
718
719 /* Bail out if no more sends are pending */
720 if (!SendsInProgress)
721 {
722 LingerWait = -1;
723 break;
724 }
725
726 /*
727 * We have to execute a sleep, so it's kind of like
728 * a block. If the socket is Nonblock, we cannot
729 * go on since asynchronous operation is expected
730 * and we cannot offer it
731 */
732 if (Socket->SharedData->NonBlocking)
733 {
734 WARN("Would block!\n");
736 Socket->SharedData->State = OldState;
737 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
738 return SOCKET_ERROR;
739 }
740
741 /* Now we can sleep, and decrement the linger wait */
742 /*
743 * FIXME: It seems Windows does some funky acceleration
744 * since the waiting seems to be longer and longer. I
745 * don't think this improves performance so much, so we
746 * wait a fixed time instead.
747 */
748 Sleep(SleepWait);
749 LingerWait -= SleepWait;
750 }
751 }
752
753 if (OldState == SocketConnected)
754 {
755 if (LingerWait <= 0)
756 {
757 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
758 DisconnectInfo.DisconnectType = LingerWait < 0 ? AFD_DISCONNECT_SEND : AFD_DISCONNECT_ABORT;
759
760 if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData->SendShutdown)) ||
761 ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData->ReceiveShutdown)))
762 {
763 /* Send IOCTL */
765 SockEvent,
766 NULL,
767 NULL,
770 &DisconnectInfo,
771 sizeof(DisconnectInfo),
772 NULL,
773 0);
774
775 /* Wait for return */
776 if (Status == STATUS_PENDING)
777 {
780 }
781 }
782 }
783 }
784
785 /* Cleanup Time! */
786 Socket->HelperContext = NULL;
787 Socket->SharedData->AsyncDisabledEvents = -1;
788 NtClose(Socket->TdiAddressHandle);
789 Socket->TdiAddressHandle = NULL;
791 Socket->TdiConnectionHandle = NULL;
792ok:
794 if (SocketListHead == Socket)
795 {
797 }
798 else
799 {
800 CurrentSocket = SocketListHead;
801 while (CurrentSocket->NextSocket)
802 {
803 if (CurrentSocket->NextSocket == Socket)
804 {
805 CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket;
806 break;
807 }
808
809 CurrentSocket = CurrentSocket->NextSocket;
810 }
811 }
813
814 /* Close the handle */
817
819 {
820 /* It is a duplicated socket, so unmap the memory */
822 NtClose(Socket->SharedDataHandle);
823 Socket->SharedData = NULL;
824 }
825 if( !References && Socket->SharedData )
826 {
827 HeapFree(GlobalHeap, 0, Socket->SharedData);
828 }
829 HeapFree(GlobalHeap, 0, Socket);
830 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
831}
832
833
834/*
835 * FUNCTION: Associates a local address with a socket
836 * ARGUMENTS:
837 * s = Socket descriptor
838 * name = Pointer to local address
839 * namelen = Length of name
840 * lpErrno = Address of buffer for error information
841 * RETURNS:
842 * 0, or SOCKET_ERROR if the socket could not be bound
843 */
844INT
845WSPAPI
847 const struct sockaddr *SocketAddress,
848 int SocketAddressLength,
849 LPINT lpErrno)
850{
851 IO_STATUS_BLOCK IOSB;
852 PAFD_BIND_DATA BindData;
853 PSOCKET_INFORMATION Socket = NULL;
855 SOCKADDR_INFO SocketInfo;
857
858 /* Get the Socket Structure associate to this Socket*/
859 Socket = GetSocketStructure(Handle);
860 if (!Socket)
861 {
862 if (lpErrno) *lpErrno = WSAENOTSOCK;
863 return SOCKET_ERROR;
864 }
865 if (Socket->SharedData->State != SocketOpen)
866 {
867 if (lpErrno) *lpErrno = WSAEINVAL;
868 return SOCKET_ERROR;
869 }
870 if (!SocketAddress || SocketAddressLength < Socket->SharedData->SizeOfLocalAddress)
871 {
872 if (lpErrno) *lpErrno = WSAEINVAL;
873 return SOCKET_ERROR;
874 }
875
876 /* Get Address Information */
877 Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
878 SocketAddressLength,
879 &SocketInfo);
880
881 if (SocketInfo.AddressInfo == SockaddrAddressInfoBroadcast && !Socket->SharedData->Broadcast)
882 {
883 if (lpErrno) *lpErrno = WSAEADDRNOTAVAIL;
884 return SOCKET_ERROR;
885 }
886
889 NULL,
891 FALSE);
892
893 if (!NT_SUCCESS(Status))
894 {
895 return SOCKET_ERROR;
896 }
897
898 /* See below */
899 BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength);
900 if (!BindData)
901 {
903 }
904
905 /* Set up Address in TDI Format */
906 BindData->Address.TAAddressCount = 1;
907 BindData->Address.Address[0].AddressLength = (USHORT)(SocketAddressLength - sizeof(SocketAddress->sa_family));
908 BindData->Address.Address[0].AddressType = SocketAddress->sa_family;
909 RtlCopyMemory (BindData->Address.Address[0].Address,
910 SocketAddress->sa_data,
911 SocketAddressLength - sizeof(SocketAddress->sa_family));
912
913 /* Set the Share Type */
914 if (Socket->SharedData->ExclusiveAddressUse)
915 {
916 BindData->ShareType = AFD_SHARE_EXCLUSIVE;
917 }
918 else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard)
919 {
920 BindData->ShareType = AFD_SHARE_WILDCARD;
921 }
922 else if (Socket->SharedData->ReuseAddresses)
923 {
924 BindData->ShareType = AFD_SHARE_REUSE;
925 }
926 else
927 {
928 BindData->ShareType = AFD_SHARE_UNIQUE;
929 }
930
931 /* Send IOCTL */
933 SockEvent,
934 NULL,
935 NULL,
936 &IOSB,
938 BindData,
939 0xA + Socket->SharedData->SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
940 BindData,
941 0xA + Socket->SharedData->SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
942
943 /* Wait for return */
944 if (Status == STATUS_PENDING)
945 {
947 Status = IOSB.Status;
948 }
949
951 HeapFree(GlobalHeap, 0, BindData);
952
954 if (Status != STATUS_SUCCESS)
955 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
956
957 /* Set up Socket Data */
958 Socket->SharedData->State = SocketBound;
959 Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
960
962 {
963 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
964 Socket->Handle,
965 Socket->TdiAddressHandle,
966 Socket->TdiConnectionHandle,
968
969 if (Status)
970 {
971 if (lpErrno) *lpErrno = Status;
972 return SOCKET_ERROR;
973 }
974 }
975
976 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
977}
978
979int
980WSPAPI
982 int Backlog,
983 LPINT lpErrno)
984{
985 IO_STATUS_BLOCK IOSB;
986 AFD_LISTEN_DATA ListenData;
987 PSOCKET_INFORMATION Socket = NULL;
990
991 /* Get the Socket Structure associate to this Socket*/
992 Socket = GetSocketStructure(Handle);
993 if (!Socket)
994 {
995 if (lpErrno) *lpErrno = WSAENOTSOCK;
996 return SOCKET_ERROR;
997 }
998
999 if (Socket->SharedData->Listening)
1000 return NO_ERROR;
1001
1004 NULL,
1006 FALSE);
1007
1008 if( !NT_SUCCESS(Status) )
1009 return SOCKET_ERROR;
1010
1011 /* Set Up Listen Structure */
1012 ListenData.UseSAN = FALSE;
1014 ListenData.Backlog = Backlog;
1015
1016 /* Send IOCTL */
1018 SockEvent,
1019 NULL,
1020 NULL,
1021 &IOSB,
1023 &ListenData,
1024 sizeof(ListenData),
1025 NULL,
1026 0);
1027
1028 /* Wait for return */
1029 if (Status == STATUS_PENDING)
1030 {
1032 Status = IOSB.Status;
1033 }
1034
1035 NtClose( SockEvent );
1036
1038 if (Status != STATUS_SUCCESS)
1039 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1040
1041 /* Set to Listening */
1042 Socket->SharedData->Listening = TRUE;
1043
1044 if (Socket->HelperEvents & WSH_NOTIFY_LISTEN)
1045 {
1046 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1047 Socket->Handle,
1048 Socket->TdiAddressHandle,
1049 Socket->TdiConnectionHandle,
1051
1052 if (Status)
1053 {
1054 if (lpErrno) *lpErrno = Status;
1055 return SOCKET_ERROR;
1056 }
1057 }
1058
1059 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1060}
1061
1062
1063int
1064WSPAPI
1065WSPSelect(IN int nfds,
1066 IN OUT fd_set *readfds OPTIONAL,
1067 IN OUT fd_set *writefds OPTIONAL,
1068 IN OUT fd_set *exceptfds OPTIONAL,
1069 IN const struct timeval *timeout OPTIONAL,
1070 OUT LPINT lpErrno)
1071{
1072 IO_STATUS_BLOCK IOSB;
1073 PAFD_POLL_INFO PollInfo;
1075 ULONG HandleCount;
1076 ULONG PollBufferSize;
1077 PVOID PollBuffer;
1078 ULONG i, j = 0, x;
1081 PSOCKET_INFORMATION Socket;
1082 SOCKET Handle;
1083 ULONG Events;
1084 fd_set selectfds;
1085
1086 /* Find out how many sockets we have, and how large the buffer needs
1087 * to be */
1088 FD_ZERO(&selectfds);
1089 if (readfds != NULL)
1090 {
1091 for (i = 0; i < readfds->fd_count; i++)
1092 {
1093 FD_SET(readfds->fd_array[i], &selectfds);
1094 }
1095 }
1096 if (writefds != NULL)
1097 {
1098 for (i = 0; i < writefds->fd_count; i++)
1099 {
1100 FD_SET(writefds->fd_array[i], &selectfds);
1101 }
1102 }
1103 if (exceptfds != NULL)
1104 {
1105 for (i = 0; i < exceptfds->fd_count; i++)
1106 {
1107 FD_SET(exceptfds->fd_array[i], &selectfds);
1108 }
1109 }
1110
1111 HandleCount = selectfds.fd_count;
1112
1113 if ( HandleCount == 0 )
1114 {
1115 WARN("No handles! Returning SOCKET_ERROR\n", HandleCount);
1116 if (lpErrno) *lpErrno = WSAEINVAL;
1117 return SOCKET_ERROR;
1118 }
1119
1120 PollBufferSize = sizeof(*PollInfo) + ((HandleCount - 1) * sizeof(AFD_HANDLE));
1121
1122 TRACE("HandleCount: %u BufferSize: %u\n", HandleCount, PollBufferSize);
1123
1124 /* Convert Timeout to NT Format */
1125 if (timeout == NULL)
1126 {
1127 Timeout.u.LowPart = -1;
1128 Timeout.u.HighPart = 0x7FFFFFFF;
1129 TRACE("Infinite timeout\n");
1130 }
1131 else
1132 {
1134 ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000), -10000);
1135 /* Negative timeouts are illegal. Since the kernel represents an
1136 * incremental timeout as a negative number, we check for a positive
1137 * result.
1138 */
1139 if (Timeout.QuadPart > 0)
1140 {
1141 if (lpErrno) *lpErrno = WSAEINVAL;
1142 return SOCKET_ERROR;
1143 }
1144 TRACE("Timeout: Orig %d.%06d kernel %d\n",
1145 timeout->tv_sec, timeout->tv_usec,
1146 Timeout.u.LowPart);
1147 }
1148
1151 NULL,
1153 FALSE);
1154
1155 if(!NT_SUCCESS(Status))
1156 {
1157 if (lpErrno)
1158 *lpErrno = WSAEFAULT;
1159
1160 ERR("NtCreateEvent failed, 0x%08x\n", Status);
1161 return SOCKET_ERROR;
1162 }
1163
1164 /* Allocate */
1165 PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
1166
1167 if (!PollBuffer)
1168 {
1169 if (lpErrno)
1170 *lpErrno = WSAEFAULT;
1172 return SOCKET_ERROR;
1173 }
1174
1175 PollInfo = (PAFD_POLL_INFO)PollBuffer;
1176
1177 RtlZeroMemory( PollInfo, PollBufferSize );
1178
1179 /* Number of handles for AFD to Check */
1180 PollInfo->Exclusive = FALSE;
1181 PollInfo->Timeout = Timeout;
1182
1183 for (i = 0; i < selectfds.fd_count; i++)
1184 {
1185 PollInfo->Handles[i].Handle = selectfds.fd_array[i];
1186 }
1187 if (readfds != NULL) {
1188 for (i = 0; i < readfds->fd_count; i++)
1189 {
1190 for (j = 0; j < HandleCount; j++)
1191 {
1192 if (PollInfo->Handles[j].Handle == readfds->fd_array[i])
1193 break;
1194 }
1195 if (j >= HandleCount)
1196 {
1197 ERR("Error while counting readfds %ld > %ld\n", j, HandleCount);
1198 if (lpErrno) *lpErrno = WSAEFAULT;
1199 HeapFree(GlobalHeap, 0, PollBuffer);
1201 return SOCKET_ERROR;
1202 }
1203 Socket = GetSocketStructure(readfds->fd_array[i]);
1204 if (!Socket)
1205 {
1206 ERR("Invalid socket handle provided in readfds %d\n", readfds->fd_array[i]);
1207 if (lpErrno) *lpErrno = WSAENOTSOCK;
1208 HeapFree(GlobalHeap, 0, PollBuffer);
1210 return SOCKET_ERROR;
1211 }
1212 PollInfo->Handles[j].Events |= AFD_EVENT_RECEIVE |
1217 //if (Socket->SharedData->OobInline != 0)
1218 // PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
1219 }
1220 }
1221 if (writefds != NULL)
1222 {
1223 for (i = 0; i < writefds->fd_count; i++)
1224 {
1225 for (j = 0; j < HandleCount; j++)
1226 {
1227 if (PollInfo->Handles[j].Handle == writefds->fd_array[i])
1228 break;
1229 }
1230 if (j >= HandleCount)
1231 {
1232 ERR("Error while counting writefds %ld > %ld\n", j, HandleCount);
1233 if (lpErrno) *lpErrno = WSAEFAULT;
1234 HeapFree(GlobalHeap, 0, PollBuffer);
1236 return SOCKET_ERROR;
1237 }
1238 Socket = GetSocketStructure(writefds->fd_array[i]);
1239 if (!Socket)
1240 {
1241 ERR("Invalid socket handle provided in writefds %d\n", writefds->fd_array[i]);
1242 if (lpErrno) *lpErrno = WSAENOTSOCK;
1243 HeapFree(GlobalHeap, 0, PollBuffer);
1245 return SOCKET_ERROR;
1246 }
1247 PollInfo->Handles[j].Handle = writefds->fd_array[i];
1248 PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
1249 if (Socket->SharedData->NonBlocking != 0)
1250 PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT;
1251 }
1252 }
1253 if (exceptfds != NULL)
1254 {
1255 for (i = 0; i < exceptfds->fd_count; i++)
1256 {
1257 for (j = 0; j < HandleCount; j++)
1258 {
1259 if (PollInfo->Handles[j].Handle == exceptfds->fd_array[i])
1260 break;
1261 }
1262 if (j > HandleCount)
1263 {
1264 ERR("Error while counting exceptfds %ld > %ld\n", j, HandleCount);
1265 if (lpErrno) *lpErrno = WSAEFAULT;
1266 HeapFree(GlobalHeap, 0, PollBuffer);
1268 return SOCKET_ERROR;
1269 }
1270 Socket = GetSocketStructure(exceptfds->fd_array[i]);
1271 if (!Socket)
1272 {
1273 TRACE("Invalid socket handle provided in exceptfds %d\n", exceptfds->fd_array[i]);
1274 if (lpErrno) *lpErrno = WSAENOTSOCK;
1275 HeapFree(GlobalHeap, 0, PollBuffer);
1277 return SOCKET_ERROR;
1278 }
1279 PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
1280 if (Socket->SharedData->OobInline == 0)
1281 PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
1282 if (Socket->SharedData->NonBlocking != 0)
1283 PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT_FAIL;
1284 }
1285 }
1286
1287 PollInfo->HandleCount = HandleCount;
1288 PollBufferSize = FIELD_OFFSET(AFD_POLL_INFO, Handles) + PollInfo->HandleCount * sizeof(AFD_HANDLE);
1289
1290 /* Send IOCTL */
1292 SockEvent,
1293 NULL,
1294 NULL,
1295 &IOSB,
1297 PollInfo,
1298 PollBufferSize,
1299 PollInfo,
1300 PollBufferSize);
1301
1302 TRACE("DeviceIoControlFile => %x\n", Status);
1303
1304 /* Wait for Completion */
1305 if (Status == STATUS_PENDING)
1306 {
1308 Status = IOSB.Status;
1309 }
1310
1311 /* Clear the Structures */
1312 if( readfds )
1313 FD_ZERO(readfds);
1314 if( writefds )
1315 FD_ZERO(writefds);
1316 if( exceptfds )
1317 FD_ZERO(exceptfds);
1318
1319 /* Loop through return structure */
1320 HandleCount = PollInfo->HandleCount;
1321
1322 /* Return in FDSET Format */
1323 for (i = 0; i < HandleCount; i++)
1324 {
1325 Events = PollInfo->Handles[i].Events;
1326 Handle = PollInfo->Handles[i].Handle;
1327 for(x = 1; x; x<<=1)
1328 {
1329 Socket = GetSocketStructure(Handle);
1330 if (!Socket)
1331 {
1332 TRACE("Invalid socket handle found %d\n", Handle);
1333 if (lpErrno) *lpErrno = WSAENOTSOCK;
1334 HeapFree(GlobalHeap, 0, PollBuffer);
1336 return SOCKET_ERROR;
1337 }
1338 switch (Events & x)
1339 {
1340 case AFD_EVENT_RECEIVE:
1342 case AFD_EVENT_ABORT:
1343 case AFD_EVENT_ACCEPT:
1344 case AFD_EVENT_CLOSE:
1345 TRACE("Event %x on handle %x\n",
1346 Events,
1347 Handle);
1348 if ((Events & x) == AFD_EVENT_DISCONNECT || (Events & x) == AFD_EVENT_CLOSE)
1350 if ((Events & x) == AFD_EVENT_ABORT)
1352 if( readfds )
1353 FD_SET(Handle, readfds);
1354 break;
1355 case AFD_EVENT_SEND:
1356 TRACE("Event %x on handle %x\n",
1357 Events,
1358 Handle);
1359 if (writefds)
1360 FD_SET(Handle, writefds);
1361 break;
1362 case AFD_EVENT_CONNECT:
1363 TRACE("Event %x on handle %x\n",
1364 Events,
1365 Handle);
1366 if( writefds && Socket->SharedData->NonBlocking != 0 )
1367 FD_SET(Handle, writefds);
1368 break;
1370 TRACE("Event %x on handle %x\n",
1371 Events,
1372 Handle);
1373 if( readfds && Socket->SharedData->OobInline != 0 )
1374 FD_SET(Handle, readfds);
1375 if( exceptfds && Socket->SharedData->OobInline == 0 )
1376 FD_SET(Handle, exceptfds);
1377 break;
1379 TRACE("Event %x on handle %x\n",
1380 Events,
1381 Handle);
1382 if( exceptfds && Socket->SharedData->NonBlocking != 0 )
1383 FD_SET(Handle, exceptfds);
1384 break;
1385 }
1386 }
1387 }
1388
1389 HeapFree( GlobalHeap, 0, PollBuffer );
1390 NtClose( SockEvent );
1391
1392 if( lpErrno )
1393 {
1394 switch( IOSB.Status )
1395 {
1396 case STATUS_SUCCESS:
1397 case STATUS_TIMEOUT:
1398 *lpErrno = 0;
1399 break;
1400 default:
1401 *lpErrno = WSAEINVAL;
1402 break;
1403 }
1404 TRACE("*lpErrno = %x\n", *lpErrno);
1405 }
1406
1407 HandleCount = (readfds ? readfds->fd_count : 0) +
1408 (writefds && writefds != readfds ? writefds->fd_count : 0) +
1409 (exceptfds && exceptfds != readfds && exceptfds != writefds ? exceptfds->fd_count : 0);
1410
1411 TRACE("%d events\n", HandleCount);
1412
1413 return HandleCount;
1414}
1415
1416DWORD
1418{
1419 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
1420 union
1421 {
1422 FILETIME ft;
1423 ULONGLONG ll;
1424 } u1970, Time;
1425
1427 SystemTimeToFileTime(&st1970, &u1970.ft);
1428 return (DWORD)((Time.ll - u1970.ll) / 10000000ULL);
1429}
1430
1432SOCKET
1433WSPAPI
1436 _Out_writes_bytes_to_opt_(*addrlen, *addrlen) struct sockaddr FAR *SocketAddress,
1437 _Inout_opt_ LPINT SocketAddressLength,
1438 _In_opt_ LPCONDITIONPROC lpfnCondition,
1439 _In_opt_ DWORD_PTR dwCallbackData,
1440 _Out_ LPINT lpErrno)
1441{
1442 IO_STATUS_BLOCK IOSB;
1443 PAFD_RECEIVED_ACCEPT_DATA ListenReceiveData;
1444 AFD_ACCEPT_DATA AcceptData;
1445 AFD_DEFER_ACCEPT_DATA DeferData;
1446 AFD_PENDING_ACCEPT_DATA PendingAcceptData;
1447 PSOCKET_INFORMATION Socket = NULL;
1449 struct fd_set ReadSet;
1450 struct timeval Timeout;
1451 PVOID PendingData = NULL;
1452 ULONG PendingDataLength = 0;
1453 PVOID CalleeDataBuffer;
1454 WSABUF CallerData, CalleeID, CallerID, CalleeData;
1456 GROUP GroupID = 0;
1457 ULONG CallBack;
1459 PSOCKET_INFORMATION AcceptSocketInfo;
1460 UCHAR ReceiveBuffer[0x1A];
1462
1463 /* Get the Socket Structure associate to this Socket*/
1464 Socket = GetSocketStructure(Handle);
1465 if (!Socket)
1466 {
1467 if (lpErrno) *lpErrno = WSAENOTSOCK;
1468 return SOCKET_ERROR;
1469 }
1470 if (!Socket->SharedData->Listening)
1471 {
1472 if (lpErrno) *lpErrno = WSAEINVAL;
1473 return SOCKET_ERROR;
1474 }
1475 if ((SocketAddress && !SocketAddressLength) ||
1476 (SocketAddressLength && !SocketAddress) ||
1477 (SocketAddressLength && *SocketAddressLength < sizeof(SOCKADDR)))
1478 {
1479 if (lpErrno) *lpErrno = WSAEFAULT;
1480 return INVALID_SOCKET;
1481 }
1482
1485 NULL,
1487 FALSE);
1488
1489 if( !NT_SUCCESS(Status) )
1490 {
1491 return SOCKET_ERROR;
1492 }
1493
1494 /* Dynamic Structure...ugh */
1495 ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
1496
1497 /* If this is non-blocking, make sure there's something for us to accept */
1498 if (Socket->SharedData->NonBlocking)
1499 {
1500 FD_ZERO(&ReadSet);
1501 FD_SET(Socket->Handle, &ReadSet);
1502 Timeout.tv_sec=0;
1503 Timeout.tv_usec=0;
1504
1505 if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
1506 {
1508 return SOCKET_ERROR;
1509 }
1510
1511 if (ReadSet.fd_array[0] != Socket->Handle)
1512 {
1514 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
1515 return SOCKET_ERROR;
1516 }
1517 }
1518
1519 /* Send IOCTL */
1521 SockEvent,
1522 NULL,
1523 NULL,
1524 &IOSB,
1526 NULL,
1527 0,
1528 ListenReceiveData,
1529 0xA + sizeof(*ListenReceiveData));
1530
1531 /* Wait for return */
1532 if (Status == STATUS_PENDING)
1533 {
1535 Status = IOSB.Status;
1536 }
1537
1538 if (!NT_SUCCESS(Status))
1539 {
1540 NtClose( SockEvent );
1541 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1542 }
1543
1544 if (lpfnCondition != NULL)
1545 {
1546 if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECT_DATA) != 0)
1547 {
1548 /* Find out how much data is pending */
1549 PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1550 PendingAcceptData.ReturnSize = TRUE;
1551
1552 /* Send IOCTL */
1554 SockEvent,
1555 NULL,
1556 NULL,
1557 &IOSB,
1559 &PendingAcceptData,
1560 sizeof(PendingAcceptData),
1561 &PendingAcceptData,
1562 sizeof(PendingAcceptData));
1563
1564 /* Wait for return */
1565 if (Status == STATUS_PENDING)
1566 {
1568 Status = IOSB.Status;
1569 }
1570
1571 if (!NT_SUCCESS(Status))
1572 {
1573 NtClose( SockEvent );
1574 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1575 }
1576
1577 /* How much data to allocate */
1578 PendingDataLength = IOSB.Information;
1579
1580 if (PendingDataLength)
1581 {
1582 /* Allocate needed space */
1583 PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
1584 if (!PendingData)
1585 {
1587 }
1588
1589 /* We want the data now */
1590 PendingAcceptData.ReturnSize = FALSE;
1591
1592 /* Send IOCTL */
1594 SockEvent,
1595 NULL,
1596 NULL,
1597 &IOSB,
1599 &PendingAcceptData,
1600 sizeof(PendingAcceptData),
1601 PendingData,
1602 PendingDataLength);
1603
1604 /* Wait for return */
1605 if (Status == STATUS_PENDING)
1606 {
1608 Status = IOSB.Status;
1609 }
1610
1611 if (!NT_SUCCESS(Status))
1612 {
1613 NtClose( SockEvent );
1614 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1615 }
1616 }
1617 }
1618
1619 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1620 {
1621 /* I don't support this yet */
1622 }
1623
1624 /* Build Callee ID */
1625 CalleeID.buf = (PVOID)Socket->LocalAddress;
1626 CalleeID.len = Socket->SharedData->SizeOfLocalAddress;
1627
1629 if (!RemoteAddress)
1630 {
1632 }
1633
1634 /* Set up Address in SOCKADDR Format */
1636 &ListenReceiveData->Address.Address[0].AddressType,
1637 sizeof(*RemoteAddress));
1638
1639 /* Build Caller ID */
1640 CallerID.buf = (PVOID)RemoteAddress;
1641 CallerID.len = sizeof(*RemoteAddress);
1642
1643 /* Build Caller Data */
1644 CallerData.buf = PendingData;
1645 CallerData.len = PendingDataLength;
1646
1647 /* Check if socket supports Conditional Accept */
1648 if (Socket->SharedData->UseDelayedAcceptance != 0)
1649 {
1650 /* Allocate Buffer for Callee Data */
1651 CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
1652 if (!CalleeDataBuffer) {
1654 }
1655 CalleeData.buf = CalleeDataBuffer;
1656 CalleeData.len = 4096;
1657 }
1658 else
1659 {
1660 /* Nothing */
1661 CalleeData.buf = 0;
1662 CalleeData.len = 0;
1663 }
1664
1665 /* Call the Condition Function */
1666 CallBack = (lpfnCondition)(&CallerID,
1667 CallerData.buf == NULL ? NULL : &CallerData,
1668 NULL,
1669 NULL,
1670 &CalleeID,
1671 CalleeData.buf == NULL ? NULL : &CalleeData,
1672 &GroupID,
1673 dwCallbackData);
1674
1675 if (((CallBack == CF_ACCEPT) && GroupID) != 0)
1676 {
1677 /* TBD: Check for Validity */
1678 }
1679
1680 if (CallBack == CF_ACCEPT)
1681 {
1682 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1683 {
1684 /* I don't support this yet */
1685 }
1686 if (CalleeData.buf)
1687 {
1688 // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0
1689 }
1690 }
1691 else
1692 {
1693 /* Callback rejected. Build Defer Structure */
1694 DeferData.SequenceNumber = ListenReceiveData->SequenceNumber;
1695 DeferData.RejectConnection = (CallBack == CF_REJECT);
1696
1697 /* Send IOCTL */
1699 SockEvent,
1700 NULL,
1701 NULL,
1702 &IOSB,
1704 &DeferData,
1705 sizeof(DeferData),
1706 NULL,
1707 0);
1708
1709 /* Wait for return */
1710 if (Status == STATUS_PENDING)
1711 {
1713 Status = IOSB.Status;
1714 }
1715
1716 NtClose( SockEvent );
1717
1718 if (!NT_SUCCESS(Status))
1719 {
1720 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1721 }
1722
1723 if (CallBack == CF_REJECT )
1724 {
1725 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1726 return SOCKET_ERROR;
1727 }
1728 else
1729 {
1730 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1731 return SOCKET_ERROR;
1732 }
1733 }
1734 }
1735
1736 /* Create a new Socket */
1738 Socket->SharedData->SocketType,
1739 Socket->SharedData->Protocol,
1740 &Socket->ProtocolInfo,
1741 GroupID,
1742 Socket->SharedData->CreateFlags,
1743 lpErrno);
1745 return SOCKET_ERROR;
1746
1747 /* Set up the Accept Structure */
1748 AcceptData.ListenHandle = (HANDLE)AcceptSocket;
1749 AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1750
1751 /* Send IOCTL to Accept */
1753 SockEvent,
1754 NULL,
1755 NULL,
1756 &IOSB,
1758 &AcceptData,
1759 sizeof(AcceptData),
1760 NULL,
1761 0);
1762
1763 /* Wait for return */
1764 if (Status == STATUS_PENDING)
1765 {
1767 Status = IOSB.Status;
1768 }
1769
1771 if (!NT_SUCCESS(Status))
1772 {
1774 WSPCloseSocket( AcceptSocket, lpErrno );
1775 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1776 }
1777
1778 AcceptSocketInfo = GetSocketStructure(AcceptSocket);
1779 if (!AcceptSocketInfo)
1780 {
1782 WSPCloseSocket( AcceptSocket, lpErrno );
1784 }
1785
1786 AcceptSocketInfo->SharedData->State = SocketConnected;
1787 AcceptSocketInfo->SharedData->ConnectTime = GetCurrentTimeInSeconds();
1788 AcceptSocketInfo->SharedData->NonBlocking = Socket->SharedData->NonBlocking;
1789
1790 /* Return Address in SOCKADDR FORMAT */
1791 if( SocketAddress )
1792 {
1793 RtlCopyMemory (SocketAddress,
1794 &ListenReceiveData->Address.Address[0].AddressType,
1795 sizeof(*RemoteAddress));
1796 if( SocketAddressLength )
1797 *SocketAddressLength = sizeof(*RemoteAddress);
1798 }
1799
1800 NtClose( SockEvent );
1801
1802 /* Re-enable Async Event */
1804
1805 TRACE("Socket %x\n", AcceptSocket);
1806
1808 {
1809 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1810 Socket->Handle,
1811 Socket->TdiAddressHandle,
1812 Socket->TdiConnectionHandle,
1814
1815 if (Status)
1816 {
1817 if (lpErrno) *lpErrno = Status;
1818 return SOCKET_ERROR;
1819 }
1820 }
1821
1822 if (lpErrno) *lpErrno = NO_ERROR;
1823
1824 /* Return Socket */
1825 return AcceptSocket;
1826}
1827
1828int
1829WSPAPI
1831 const struct sockaddr * SocketAddress,
1832 int SocketAddressLength,
1833 LPWSABUF lpCallerData,
1834 LPWSABUF lpCalleeData,
1835 LPQOS lpSQOS,
1836 LPQOS lpGQOS,
1837 LPINT lpErrno)
1838{
1839 IO_STATUS_BLOCK IOSB;
1840 PAFD_CONNECT_INFO ConnectInfo = NULL;
1841 PSOCKET_INFORMATION Socket;
1843 INT Errno;
1844 ULONG ConnectDataLength;
1845 ULONG InConnectDataLength;
1846 INT BindAddressLength;
1847 PSOCKADDR BindAddress;
1849 int SocketDataLength;
1850
1851 TRACE("Called (%lx) %lx:%d\n", Handle, ((const struct sockaddr_in *)SocketAddress)->sin_addr, ((const struct sockaddr_in *)SocketAddress)->sin_port);
1852
1853 /* Get the Socket Structure associate to this Socket*/
1854 Socket = GetSocketStructure(Handle);
1855 if (!Socket)
1856 {
1857 if (lpErrno) *lpErrno = WSAENOTSOCK;
1858 return SOCKET_ERROR;
1859 }
1860
1863 NULL,
1865 FALSE);
1866
1867 if (!NT_SUCCESS(Status))
1868 return SOCKET_ERROR;
1869
1870 /* Bind us First */
1871 if (Socket->SharedData->State == SocketOpen)
1872 {
1873 /* Get the Wildcard Address */
1874 BindAddressLength = Socket->HelperData->MaxWSAddressLength;
1875 BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength);
1876 if (!BindAddress)
1877 {
1880 }
1882 BindAddress,
1883 &BindAddressLength);
1884 /* Bind it */
1885 if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR)
1886 return SOCKET_ERROR;
1887 }
1888
1889 /* Set the Connect Data */
1890 if (lpCallerData != NULL)
1891 {
1892 ConnectDataLength = lpCallerData->len;
1894 SockEvent,
1895 NULL,
1896 NULL,
1897 &IOSB,
1899 lpCallerData->buf,
1900 ConnectDataLength,
1901 NULL,
1902 0);
1903 /* Wait for return */
1904 if (Status == STATUS_PENDING)
1905 {
1907 Status = IOSB.Status;
1908 }
1909
1910 if (Status != STATUS_SUCCESS)
1911 goto notify;
1912 }
1913
1914 /* Calculate the size of SocketAddress->sa_data */
1915 SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
1916
1917 /* Allocate a connection info buffer with SocketDataLength bytes of payload */
1918 ConnectInfo = HeapAlloc(GetProcessHeap(), 0,
1920 RemoteAddress.Address[0].Address[SocketDataLength]));
1921 if (!ConnectInfo)
1922 {
1924 goto notify;
1925 }
1926
1927 /* Set up Address in TDI Format */
1928 ConnectInfo->RemoteAddress.TAAddressCount = 1;
1929 ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
1930 ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
1932 SocketAddress->sa_data,
1933 SocketDataLength);
1934
1935 /*
1936 * Disable FD_WRITE and FD_CONNECT
1937 * The latter fixes a race condition where the FD_CONNECT is re-enabled
1938 * at the end of this function right after the Async Thread disables it.
1939 * This should only happen at the *next* WSPConnect
1940 */
1941 if (Socket->SharedData->AsyncEvents & FD_CONNECT)
1942 {
1944 }
1945
1946 /* Tell AFD that we want Connection Data back, have it allocate a buffer */
1947 if (lpCalleeData != NULL)
1948 {
1949 InConnectDataLength = lpCalleeData->len;
1951 SockEvent,
1952 NULL,
1953 NULL,
1954 &IOSB,
1956 &InConnectDataLength,
1957 sizeof(InConnectDataLength),
1958 NULL,
1959 0);
1960
1961 /* Wait for return */
1962 if (Status == STATUS_PENDING)
1963 {
1965 Status = IOSB.Status;
1966 }
1967
1968 if (Status != STATUS_SUCCESS)
1969 goto notify;
1970 }
1971
1972 /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */
1973 ConnectInfo->Root = 0;
1974 ConnectInfo->UseSAN = FALSE;
1975 ConnectInfo->Unknown = 0;
1976
1977 /* FIXME: Handle Async Connect */
1978 if (Socket->SharedData->NonBlocking)
1979 {
1980 ERR("Async Connect UNIMPLEMENTED!\n");
1981 }
1982
1983 /* Send IOCTL */
1985 SockEvent,
1986 NULL,
1987 NULL,
1988 &IOSB,
1990 ConnectInfo,
1991 0x22,
1992 NULL,
1993 0);
1994 /* Wait for return */
1995 if (Status == STATUS_PENDING)
1996 {
1998 Status = IOSB.Status;
1999 }
2000
2002 if (Status != STATUS_SUCCESS)
2003 goto notify;
2004
2005 Socket->SharedData->State = SocketConnected;
2006 Socket->TdiConnectionHandle = (HANDLE)IOSB.Information;
2008
2009 /* Get any pending connect data */
2010 if (lpCalleeData != NULL)
2011 {
2013 SockEvent,
2014 NULL,
2015 NULL,
2016 &IOSB,
2018 NULL,
2019 0,
2020 lpCalleeData->buf,
2021 lpCalleeData->len);
2022 /* Wait for return */
2023 if (Status == STATUS_PENDING)
2024 {
2026 Status = IOSB.Status;
2027 }
2028 }
2029
2030 TRACE("Ending %lx\n", IOSB.Status);
2031
2032notify:
2033 if (ConnectInfo) HeapFree(GetProcessHeap(), 0, ConnectInfo);
2034
2035 /* Re-enable Async Event */
2037
2038 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
2040
2042
2044 {
2045 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2046 Socket->Handle,
2047 Socket->TdiAddressHandle,
2048 Socket->TdiConnectionHandle,
2050
2051 if (Errno)
2052 {
2053 if (lpErrno) *lpErrno = Errno;
2054 return SOCKET_ERROR;
2055 }
2056 }
2058 {
2059 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2060 Socket->Handle,
2061 Socket->TdiAddressHandle,
2062 Socket->TdiConnectionHandle,
2064
2065 if (Errno)
2066 {
2067 if (lpErrno) *lpErrno = Errno;
2068 return SOCKET_ERROR;
2069 }
2070 }
2071
2072 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
2073}
2074int
2075WSPAPI
2077 int HowTo,
2078 LPINT lpErrno)
2079
2080{
2081 IO_STATUS_BLOCK IOSB;
2082 AFD_DISCONNECT_INFO DisconnectInfo;
2083 PSOCKET_INFORMATION Socket = NULL;
2086
2087 TRACE("Called\n");
2088
2089 /* Get the Socket Structure associate to this Socket*/
2090 Socket = GetSocketStructure(Handle);
2091 if (!Socket)
2092 {
2093 if (lpErrno) *lpErrno = WSAENOTSOCK;
2094 return SOCKET_ERROR;
2095 }
2096
2099 NULL,
2101 FALSE);
2102
2103 if( !NT_SUCCESS(Status) )
2104 return SOCKET_ERROR;
2105
2106 /* Set AFD Disconnect Type */
2107 switch (HowTo)
2108 {
2109 case SD_RECEIVE:
2110 DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
2111 Socket->SharedData->ReceiveShutdown = TRUE;
2112 break;
2113 case SD_SEND:
2114 DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
2115 Socket->SharedData->SendShutdown = TRUE;
2116 break;
2117 case SD_BOTH:
2119 Socket->SharedData->ReceiveShutdown = TRUE;
2120 Socket->SharedData->SendShutdown = TRUE;
2121 break;
2122 }
2123
2124 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1000000);
2125
2126 /* Send IOCTL */
2128 SockEvent,
2129 NULL,
2130 NULL,
2131 &IOSB,
2133 &DisconnectInfo,
2134 sizeof(DisconnectInfo),
2135 NULL,
2136 0);
2137
2138 /* Wait for return */
2139 if (Status == STATUS_PENDING)
2140 {
2142 Status = IOSB.Status;
2143 }
2144
2145 TRACE("Ending\n");
2146
2147 NtClose( SockEvent );
2148
2150 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
2151}
2152
2153
2154INT
2155WSPAPI
2158 IN OUT LPINT NameLength,
2159 OUT LPINT lpErrno)
2160{
2161 IO_STATUS_BLOCK IOSB;
2162 ULONG TdiAddressSize;
2163 PTDI_ADDRESS_INFO TdiAddress;
2164 PTRANSPORT_ADDRESS SocketAddress;
2165 PSOCKET_INFORMATION Socket = NULL;
2168
2169 /* Get the Socket Structure associate to this Socket*/
2170 Socket = GetSocketStructure(Handle);
2171 if (!Socket)
2172 {
2173 if (lpErrno) *lpErrno = WSAENOTSOCK;
2174 return SOCKET_ERROR;
2175 }
2176
2177 if (!Name || !NameLength)
2178 {
2179 if (lpErrno) *lpErrno = WSAEFAULT;
2180 return SOCKET_ERROR;
2181 }
2182
2185 NULL,
2187 FALSE);
2188
2189 if( !NT_SUCCESS(Status) )
2190 return SOCKET_ERROR;
2191
2192 /* Allocate a buffer for the address */
2193 TdiAddressSize =
2195 TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2196
2197 if ( TdiAddress == NULL )
2198 {
2199 NtClose( SockEvent );
2200 if (lpErrno) *lpErrno = WSAENOBUFS;
2201 return SOCKET_ERROR;
2202 }
2203
2204 SocketAddress = &TdiAddress->Address;
2205
2206 /* Send IOCTL */
2208 SockEvent,
2209 NULL,
2210 NULL,
2211 &IOSB,
2213 NULL,
2214 0,
2215 TdiAddress,
2216 TdiAddressSize);
2217
2218 /* Wait for return */
2219 if (Status == STATUS_PENDING)
2220 {
2222 Status = IOSB.Status;
2223 }
2224
2225 NtClose( SockEvent );
2226
2227 if (NT_SUCCESS(Status))
2228 {
2229 if (*NameLength >= Socket->SharedData->SizeOfLocalAddress)
2230 {
2231 Name->sa_family = SocketAddress->Address[0].AddressType;
2232 RtlCopyMemory (Name->sa_data,
2233 SocketAddress->Address[0].Address,
2234 SocketAddress->Address[0].AddressLength);
2235 *NameLength = Socket->SharedData->SizeOfLocalAddress;
2236 TRACE("NameLength %d Address: %x Port %x\n",
2237 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2238 ((struct sockaddr_in *)Name)->sin_port);
2239 HeapFree(GlobalHeap, 0, TdiAddress);
2240 return 0;
2241 }
2242 else
2243 {
2244 HeapFree(GlobalHeap, 0, TdiAddress);
2245 if (lpErrno) *lpErrno = WSAEFAULT;
2246 return SOCKET_ERROR;
2247 }
2248 }
2249
2250 HeapFree(GlobalHeap, 0, TdiAddress);
2251
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 PTRANSPORT_ADDRESS SocketAddress;
2266 PSOCKET_INFORMATION Socket = NULL;
2269
2270 /* Get the Socket Structure associate to this Socket*/
2271 Socket = GetSocketStructure(s);
2272 if (!Socket)
2273 {
2274 if (lpErrno) *lpErrno = WSAENOTSOCK;
2275 return SOCKET_ERROR;
2276 }
2277
2278 if (Socket->SharedData->State != SocketConnected)
2279 {
2280 if (lpErrno) *lpErrno = WSAENOTCONN;
2281 return SOCKET_ERROR;
2282 }
2283
2284 if (!Name || !NameLength)
2285 {
2286 if (lpErrno) *lpErrno = WSAEFAULT;
2287 return SOCKET_ERROR;
2288 }
2289
2292 NULL,
2294 FALSE);
2295
2296 if( !NT_SUCCESS(Status) )
2297 return SOCKET_ERROR;
2298
2299 /* Allocate a buffer for the address */
2300 TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress;
2301 SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2302
2303 if ( SocketAddress == NULL )
2304 {
2305 NtClose( SockEvent );
2306 if (lpErrno) *lpErrno = WSAENOBUFS;
2307 return SOCKET_ERROR;
2308 }
2309
2310 /* Send IOCTL */
2312 SockEvent,
2313 NULL,
2314 NULL,
2315 &IOSB,
2317 NULL,
2318 0,
2319 SocketAddress,
2320 TdiAddressSize);
2321
2322 /* Wait for return */
2323 if (Status == STATUS_PENDING)
2324 {
2326 Status = IOSB.Status;
2327 }
2328
2329 NtClose( SockEvent );
2330
2331 if (NT_SUCCESS(Status))
2332 {
2333 if (*NameLength >= Socket->SharedData->SizeOfRemoteAddress)
2334 {
2335 Name->sa_family = SocketAddress->Address[0].AddressType;
2336 RtlCopyMemory (Name->sa_data,
2337 SocketAddress->Address[0].Address,
2338 SocketAddress->Address[0].AddressLength);
2339 *NameLength = Socket->SharedData->SizeOfRemoteAddress;
2340 TRACE("NameLength %d Address: %x Port %x\n",
2341 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2342 ((struct sockaddr_in *)Name)->sin_port);
2343 HeapFree(GlobalHeap, 0, SocketAddress);
2344 return 0;
2345 }
2346 else
2347 {
2348 HeapFree(GlobalHeap, 0, SocketAddress);
2349 if (lpErrno) *lpErrno = WSAEFAULT;
2350 return SOCKET_ERROR;
2351 }
2352 }
2353
2354 HeapFree(GlobalHeap, 0, SocketAddress);
2355
2356 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2357}
2358
2359INT
2360WSPAPI
2363 IN LPVOID lpvInBuffer,
2364 IN DWORD cbInBuffer,
2365 OUT LPVOID lpvOutBuffer,
2366 IN DWORD cbOutBuffer,
2367 OUT LPDWORD lpcbBytesReturned,
2369 IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
2370 IN LPWSATHREADID lpThreadId,
2371 OUT LPINT lpErrno)
2372{
2373 PSOCKET_INFORMATION Socket = NULL;
2374 BOOL NeedsCompletion = lpOverlapped != NULL;
2375 BOOLEAN NonBlocking;
2376 INT Errno = NO_ERROR, Ret = SOCKET_ERROR;
2377 DWORD cbRet = 0;
2378
2379 /* Get the Socket Structure associate to this Socket*/
2380 Socket = GetSocketStructure(Handle);
2381 if (!Socket)
2382 {
2383 if(lpErrno)
2384 *lpErrno = WSAENOTSOCK;
2385 return SOCKET_ERROR;
2386 }
2387
2388 if (!lpcbBytesReturned && !lpOverlapped)
2389 {
2390 if(lpErrno)
2391 *lpErrno = WSAEFAULT;
2392 return SOCKET_ERROR;
2393 }
2394
2395 switch( dwIoControlCode )
2396 {
2397 case FIONBIO:
2398 if( cbInBuffer < sizeof(INT) || IS_INTRESOURCE(lpvInBuffer) )
2399 {
2400 Errno = WSAEFAULT;
2401 break;
2402 }
2403 NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
2404 /* Don't allow to go in blocking mode if WSPAsyncSelect or WSPEventSelect is pending */
2405 if (!NonBlocking)
2406 {
2407 /* If there is an WSPAsyncSelect pending, fail with WSAEINVAL */
2408 if (Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents))
2409 {
2410 Errno = WSAEINVAL;
2411 break;
2412 }
2413 /* If there is an WSPEventSelect pending, fail with WSAEINVAL */
2414 if (Socket->NetworkEvents)
2415 {
2416 Errno = WSAEINVAL;
2417 break;
2418 }
2419 }
2420 Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
2421 NeedsCompletion = FALSE;
2422 Errno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL, lpOverlapped, lpCompletionRoutine);
2423 if (Errno == NO_ERROR)
2424 Ret = NO_ERROR;
2425 break;
2426 case FIONREAD:
2427 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2428 {
2429 cbRet = sizeof(ULONG);
2430 Errno = WSAEFAULT;
2431 break;
2432 }
2433 if (cbOutBuffer < sizeof(ULONG))
2434 {
2435 Errno = WSAEINVAL;
2436 break;
2437 }
2438 NeedsCompletion = FALSE;
2439 Errno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL, lpOverlapped, lpCompletionRoutine);
2440 if (Errno == NO_ERROR)
2441 {
2442 cbRet = sizeof(ULONG);
2443 Ret = NO_ERROR;
2444 }
2445 break;
2446 case SIOCATMARK:
2447 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2448 {
2449 cbRet = sizeof(BOOL);
2450 Errno = WSAEFAULT;
2451 break;
2452 }
2453 if (cbOutBuffer < sizeof(BOOL))
2454 {
2455 Errno = WSAEINVAL;
2456 break;
2457 }
2458 if (Socket->SharedData->SocketType != SOCK_STREAM)
2459 {
2460 Errno = WSAEINVAL;
2461 break;
2462 }
2463
2464 /* FIXME: Return false if OOBINLINE is true for now
2465 We should MSG_PEEK|MSG_OOB check with driver
2466 */
2467 *(BOOL*)lpvOutBuffer = !Socket->SharedData->OobInline;
2468
2469 cbRet = sizeof(BOOL);
2470 Errno = NO_ERROR;
2471 Ret = NO_ERROR;
2472 break;
2474 if (cbOutBuffer == 0)
2475 {
2476 cbRet = sizeof(PVOID);
2477 Errno = WSAEFAULT;
2478 break;
2479 }
2480
2481 if (cbInBuffer < sizeof(GUID) ||
2482 cbOutBuffer < sizeof(PVOID))
2483 {
2484 Errno = WSAEINVAL;
2485 break;
2486 }
2487
2488 {
2489 GUID AcceptExGUID = WSAID_ACCEPTEX;
2490 GUID ConnectExGUID = WSAID_CONNECTEX;
2491 GUID DisconnectExGUID = WSAID_DISCONNECTEX;
2492 GUID GetAcceptExSockaddrsGUID = WSAID_GETACCEPTEXSOCKADDRS;
2493
2494 if (IsEqualGUID(&AcceptExGUID, lpvInBuffer))
2495 {
2496 *((PVOID *)lpvOutBuffer) = WSPAcceptEx;
2497 cbRet = sizeof(PVOID);
2498 Errno = NO_ERROR;
2499 Ret = NO_ERROR;
2500 }
2501 else if (IsEqualGUID(&ConnectExGUID, lpvInBuffer))
2502 {
2503 *((PVOID *)lpvOutBuffer) = WSPConnectEx;
2504 cbRet = sizeof(PVOID);
2505 Errno = NO_ERROR;
2506 Ret = NO_ERROR;
2507 }
2508 else if (IsEqualGUID(&DisconnectExGUID, lpvInBuffer))
2509 {
2510 *((PVOID *)lpvOutBuffer) = WSPDisconnectEx;
2511 cbRet = sizeof(PVOID);
2512 Errno = NO_ERROR;
2513 Ret = NO_ERROR;
2514 }
2515 else if (IsEqualGUID(&GetAcceptExSockaddrsGUID, lpvInBuffer))
2516 {
2517 *((PVOID *)lpvOutBuffer) = WSPGetAcceptExSockaddrs;
2518 cbRet = sizeof(PVOID);
2519 Errno = NO_ERROR;
2520 /* See CORE-14966 and associated commits.
2521 * Original line below was 'Ret = NO_ERROR:'.
2522 * This caused winetest ws2_32:sock to hang.
2523 * This new Ret value allows the test to complete. */
2524 ERR("SIO_GET_EXTENSION_FUNCTION_POINTER UNIMPLEMENTED\n");
2525 Ret = SOCKET_ERROR;
2526 }
2527 else
2528 {
2529 ERR("Querying unknown extension function: %x\n", ((GUID*)lpvInBuffer)->Data1);
2530 Errno = WSAEOPNOTSUPP;
2531 }
2532 }
2533
2534 break;
2536 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2537 {
2538 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2539 Errno = WSAEFAULT;
2540 break;
2541 }
2542 if (cbOutBuffer < sizeof(INT))
2543 {
2544 Errno = WSAEINVAL;
2545 break;
2546 }
2547
2548 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2549
2550 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->iAddressCount = 1;
2551
2552 if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress)))
2553 {
2554 Errno = WSAEFAULT;
2555 break;
2556 }
2557
2558 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->SharedData->WSLocalAddress);
2559 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->SharedData->WSLocalAddress;
2560
2561 Errno = NO_ERROR;
2562 Ret = NO_ERROR;
2563 break;
2564 default:
2565 Errno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
2566 Handle,
2567 Socket->TdiAddressHandle,
2568 Socket->TdiConnectionHandle,
2570 lpvInBuffer,
2571 cbInBuffer,
2572 lpvOutBuffer,
2573 cbOutBuffer,
2574 &cbRet,
2576 lpCompletionRoutine,
2577 &NeedsCompletion);
2578
2579 if (Errno == NO_ERROR)
2580 Ret = NO_ERROR;
2581 break;
2582 }
2583 if (lpOverlapped && NeedsCompletion)
2584 {
2585 lpOverlapped->Internal = Errno;
2586 lpOverlapped->InternalHigh = cbRet;
2587 if (lpCompletionRoutine != NULL)
2588 {
2589 lpCompletionRoutine(Errno, cbRet, lpOverlapped, 0);
2590 }
2591 if (lpOverlapped->hEvent)
2592 SetEvent(lpOverlapped->hEvent);
2594 {
2595 ERR("PostQueuedCompletionStatus failed %d\n", GetLastError());
2596 }
2597 return NO_ERROR;
2598 }
2599 if (lpErrno)
2600 *lpErrno = Errno;
2601 if (lpcbBytesReturned)
2602 *lpcbBytesReturned = cbRet;
2603 return Ret;
2604}
2605
2606
2607INT
2608WSPAPI
2610 IN INT Level,
2611 IN INT OptionName,
2612 OUT CHAR FAR* OptionValue,
2613 IN OUT LPINT OptionLength,
2614 OUT LPINT lpErrno)
2615{
2616 PSOCKET_INFORMATION Socket = NULL;
2617 PVOID Buffer;
2619 BOOL BoolBuffer;
2620 DWORD DwordBuffer;
2621 INT Errno;
2622
2623 TRACE("Called\n");
2624
2625 /* Get the Socket Structure associate to this Socket*/
2626 Socket = GetSocketStructure(Handle);
2627 if (Socket == NULL)
2628 {
2629 if (lpErrno) *lpErrno = WSAENOTSOCK;
2630 return SOCKET_ERROR;
2631 }
2632 if (!OptionLength || !OptionValue)
2633 {
2634 if (lpErrno) *lpErrno = WSAEFAULT;
2635 return SOCKET_ERROR;
2636 }
2637
2638 switch (Level)
2639 {
2640 case SOL_SOCKET:
2641 switch (OptionName)
2642 {
2643 case SO_TYPE:
2644 Buffer = &Socket->SharedData->SocketType;
2645 BufferSize = sizeof(INT);
2646 break;
2647
2648 case SO_RCVBUF:
2650 BufferSize = sizeof(ULONG);
2651 break;
2652
2653 case SO_SNDBUF:
2655 BufferSize = sizeof(ULONG);
2656 break;
2657
2658 case SO_ACCEPTCONN:
2659 BoolBuffer = Socket->SharedData->Listening;
2660 Buffer = &BoolBuffer;
2661 BufferSize = sizeof(BOOL);
2662 break;
2663
2664 case SO_BROADCAST:
2665 BoolBuffer = Socket->SharedData->Broadcast;
2666 Buffer = &BoolBuffer;
2667 BufferSize = sizeof(BOOL);
2668 break;
2669
2670 case SO_DEBUG:
2671 BoolBuffer = Socket->SharedData->Debug;
2672 Buffer = &BoolBuffer;
2673 BufferSize = sizeof(BOOL);
2674 break;
2675
2676 case SO_DONTLINGER:
2677 BoolBuffer = (Socket->SharedData->LingerData.l_onoff == 0);
2678 Buffer = &BoolBuffer;
2679 BufferSize = sizeof(BOOL);
2680 break;
2681
2682 case SO_LINGER:
2683 if (Socket->SharedData->SocketType == SOCK_DGRAM)
2684 {
2685 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
2686 return SOCKET_ERROR;
2687 }
2688 Buffer = &Socket->SharedData->LingerData;
2689 BufferSize = sizeof(struct linger);
2690 break;
2691
2692 case SO_OOBINLINE:
2693 BoolBuffer = (Socket->SharedData->OobInline != 0);
2694 Buffer = &BoolBuffer;
2695 BufferSize = sizeof(BOOL);
2696 break;
2697
2698 case SO_KEEPALIVE:
2699 case SO_DONTROUTE:
2700 /* These guys go directly to the helper */
2701 goto SendToHelper;
2702
2704 BoolBuffer = (Socket->SharedData->UseDelayedAcceptance != 0);
2705 Buffer = &BoolBuffer;
2706 BufferSize = sizeof(BOOL);
2707 break;
2708
2709 case SO_REUSEADDR:
2710 BoolBuffer = (Socket->SharedData->ReuseAddresses != 0);
2711 Buffer = &BoolBuffer;
2712 BufferSize = sizeof(BOOL);
2713 break;
2714
2716 BoolBuffer = (Socket->SharedData->ExclusiveAddressUse != 0);
2717 Buffer = &BoolBuffer;
2718 BufferSize = sizeof(BOOL);
2719 break;
2720
2721 case SO_ERROR:
2722 Buffer = &Socket->SharedData->SocketLastError;
2723 BufferSize = sizeof(INT);
2724 break;
2725
2726 case SO_CONNECT_TIME:
2727 DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
2728 Buffer = &DwordBuffer;
2729 BufferSize = sizeof(DWORD);
2730 break;
2731
2732 case SO_SNDTIMEO:
2733 Buffer = &Socket->SharedData->SendTimeout;
2734 BufferSize = sizeof(DWORD);
2735 break;
2736 case SO_RCVTIMEO:
2737 Buffer = &Socket->SharedData->RecvTimeout;
2738 BufferSize = sizeof(DWORD);
2739 break;
2740 case SO_PROTOCOL_INFOW:
2741 Buffer = &Socket->ProtocolInfo;
2742 BufferSize = sizeof(Socket->ProtocolInfo);
2743 break;
2744
2745 case SO_GROUP_ID:
2746 case SO_GROUP_PRIORITY:
2747 case SO_MAX_MSG_SIZE:
2748
2749 default:
2750 DbgPrint("MSAFD: Get unknown optname %x\n", OptionName);
2751 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
2752 return SOCKET_ERROR;
2753 }
2754
2755 if (*OptionLength < BufferSize)
2756 {
2757 if (lpErrno) *lpErrno = WSAEFAULT;
2758 *OptionLength = BufferSize;
2759 return SOCKET_ERROR;
2760 }
2761 RtlCopyMemory(OptionValue, Buffer, BufferSize);
2762
2763 return 0;
2764
2765 default:
2766 if (lpErrno) *lpErrno = WSAEINVAL;
2767 return SOCKET_ERROR;
2768 }
2769
2770SendToHelper:
2771 Errno = Socket->HelperData->WSHGetSocketInformation(Socket->HelperContext,
2772 Handle,
2773 Socket->TdiAddressHandle,
2774 Socket->TdiConnectionHandle,
2775 Level,
2776 OptionName,
2777 OptionValue,
2778 (LPINT)OptionLength);
2779 if (lpErrno) *lpErrno = Errno;
2780 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
2781}
2782
2783INT
2784WSPAPI
2786 IN SOCKET s,
2787 IN INT level,
2788 IN INT optname,
2789 IN CONST CHAR FAR* optval,
2790 IN INT optlen,
2791 OUT LPINT lpErrno)
2792{
2793 PSOCKET_INFORMATION Socket;
2794 INT Errno;
2795
2796 /* Get the Socket Structure associate to this Socket*/
2797 Socket = GetSocketStructure(s);
2798 if (Socket == NULL)
2799 {
2800 if (lpErrno) *lpErrno = WSAENOTSOCK;
2801 return SOCKET_ERROR;
2802 }
2803 if (!optval)
2804 {
2805 if (lpErrno) *lpErrno = WSAEFAULT;
2806 return SOCKET_ERROR;
2807 }
2808
2809
2810 /* FIXME: We should handle some more cases here */
2811 if (level == SOL_SOCKET)
2812 {
2813 switch (optname)
2814 {
2815 case SO_BROADCAST:
2816 if (optlen < sizeof(BOOL))
2817 {
2818 if (lpErrno) *lpErrno = WSAEFAULT;
2819 return SOCKET_ERROR;
2820 }
2821 Socket->SharedData->Broadcast = (*optval != 0) ? 1 : 0;
2822 return NO_ERROR;
2823
2824 case SO_OOBINLINE:
2825 if (optlen < sizeof(BOOL))
2826 {
2827 if (lpErrno) *lpErrno = WSAEFAULT;
2828 return SOCKET_ERROR;
2829 }
2830 Socket->SharedData->OobInline = (*optval != 0) ? 1 : 0;
2831 return NO_ERROR;
2832
2833 case SO_DONTLINGER:
2834 if (optlen < sizeof(BOOL))
2835 {
2836 if (lpErrno) *lpErrno = WSAEFAULT;
2837 return SOCKET_ERROR;
2838 }
2839 Socket->SharedData->LingerData.l_onoff = (*optval != 0) ? 0 : 1;
2840 return NO_ERROR;
2841
2842 case SO_REUSEADDR:
2843 if (optlen < sizeof(BOOL))
2844 {
2845 if (lpErrno) *lpErrno = WSAEFAULT;
2846 return SOCKET_ERROR;
2847 }
2848 Socket->SharedData->ReuseAddresses = (*optval != 0) ? 1 : 0;
2849 return NO_ERROR;
2850
2852 if (optlen < sizeof(BOOL))
2853 {
2854 if (lpErrno) *lpErrno = WSAEFAULT;
2855 return SOCKET_ERROR;
2856 }
2857 Socket->SharedData->ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
2858 return NO_ERROR;
2859
2860 case SO_LINGER:
2861 if (optlen < sizeof(struct linger))
2862 {
2863 if (lpErrno) *lpErrno = WSAEFAULT;
2864 return SOCKET_ERROR;
2865 }
2867 optval,
2868 sizeof(struct linger));
2869 return NO_ERROR;
2870
2871 case SO_SNDBUF:
2872 if (optlen < sizeof(ULONG))
2873 {
2874 if (lpErrno) *lpErrno = WSAEFAULT;
2875 return SOCKET_ERROR;
2876 }
2877
2878 SetSocketInformation(Socket,
2880 NULL,
2881 (PULONG)optval,
2882 NULL,
2883 NULL,
2884 NULL);
2885 GetSocketInformation(Socket,
2887 NULL,
2888 &Socket->SharedData->SizeOfSendBuffer,
2889 NULL,
2890 NULL,
2891 NULL);
2892
2893 return NO_ERROR;
2894
2895 case SO_RCVBUF:
2896 if (optlen < sizeof(ULONG))
2897 {
2898 if (lpErrno) *lpErrno = WSAEFAULT;
2899 return SOCKET_ERROR;
2900 }
2901
2902 /* FIXME: We should not have to limit the packet receive buffer size like this. workaround for CORE-15804 */
2903 if (*(PULONG)optval > 0x2000)
2904 *(PULONG)optval = 0x2000;
2905
2906 SetSocketInformation(Socket,
2908 NULL,
2909 (PULONG)optval,
2910 NULL,
2911 NULL,
2912 NULL);
2913 GetSocketInformation(Socket,
2915 NULL,
2916 &Socket->SharedData->SizeOfRecvBuffer,
2917 NULL,
2918 NULL,
2919 NULL);
2920
2921 return NO_ERROR;
2922
2923 case SO_ERROR:
2924 if (optlen < sizeof(INT))
2925 {
2926 if (lpErrno) *lpErrno = WSAEFAULT;
2927 return SOCKET_ERROR;
2928 }
2929
2931 optval,
2932 sizeof(INT));
2933 return NO_ERROR;
2934
2935 case SO_SNDTIMEO:
2936 if (optlen < sizeof(DWORD))
2937 {
2938 if (lpErrno) *lpErrno = WSAEFAULT;
2939 return SOCKET_ERROR;
2940 }
2941
2943 optval,
2944 sizeof(DWORD));
2945 return NO_ERROR;
2946
2947 case SO_RCVTIMEO:
2948 if (optlen < sizeof(DWORD))
2949 {
2950 if (lpErrno) *lpErrno = WSAEFAULT;
2951 return SOCKET_ERROR;
2952 }
2953
2955 optval,
2956 sizeof(DWORD));
2957 return NO_ERROR;
2958
2959 case SO_KEEPALIVE:
2960 case SO_DONTROUTE:
2961 /* These go directly to the helper dll */
2962 goto SendToHelper;
2963
2964 default:
2965 /* Obviously this is a hack */
2966 ERR("MSAFD: Set unknown optname %x\n", optname);
2967 return NO_ERROR;
2968 }
2969 }
2970
2971SendToHelper:
2972 Errno = Socket->HelperData->WSHSetSocketInformation(Socket->HelperContext,
2973 s,
2974 Socket->TdiAddressHandle,
2975 Socket->TdiConnectionHandle,
2976 level,
2977 optname,
2978 (PCHAR)optval,
2979 optlen);
2980 if (lpErrno) *lpErrno = Errno;
2981 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
2982}
2983
2984/*
2985 * FUNCTION: Initialize service provider for a client
2986 * ARGUMENTS:
2987 * wVersionRequested = Highest WinSock SPI version that the caller can use
2988 * lpWSPData = Address of WSPDATA structure to initialize
2989 * lpProtocolInfo = Pointer to structure that defines the desired protocol
2990 * UpcallTable = Pointer to upcall table of the WinSock DLL
2991 * lpProcTable = Address of procedure table to initialize
2992 * RETURNS:
2993 * Status of operation
2994 */
2996int
2997WSPAPI
2999 _In_ WORD wVersionRequested,
3000 _In_ LPWSPDATA lpWSPData,
3001 _In_ LPWSAPROTOCOL_INFOW lpProtocolInfo,
3002 _In_ WSPUPCALLTABLE UpcallTable,
3003 _Out_ LPWSPPROC_TABLE lpProcTable)
3004{
3006
3007 if (((LOBYTE(wVersionRequested) == 2) && (HIBYTE(wVersionRequested) < 2)) ||
3008 (LOBYTE(wVersionRequested) < 2))
3009 {
3010 ERR("WSPStartup NOT SUPPORTED for version 0x%X\n", wVersionRequested);
3011 return WSAVERNOTSUPPORTED;
3012 }
3013 else
3014 Status = NO_ERROR;
3015 /* FIXME: Enable all cases of WSPStartup status */
3016 Upcalls = UpcallTable;
3017
3018 if (Status == NO_ERROR)
3019 {
3020 lpProcTable->lpWSPAccept = WSPAccept;
3021 lpProcTable->lpWSPAddressToString = WSPAddressToString;
3022 lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;
3023 lpProcTable->lpWSPBind = WSPBind;
3024 lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;
3025 lpProcTable->lpWSPCleanup = WSPCleanup;
3026 lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
3027 lpProcTable->lpWSPConnect = WSPConnect;
3028 lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;
3029 lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;
3030 lpProcTable->lpWSPEventSelect = WSPEventSelect;
3031 lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;
3032 lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
3033 lpProcTable->lpWSPGetSockName = WSPGetSockName;
3034 lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;
3035 lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;
3036 lpProcTable->lpWSPIoctl = WSPIoctl;
3037 lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf;
3038 lpProcTable->lpWSPListen = WSPListen;
3039 lpProcTable->lpWSPRecv = WSPRecv;
3040 lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;
3041 lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
3042 lpProcTable->lpWSPSelect = WSPSelect;
3043 lpProcTable->lpWSPSend = WSPSend;
3044 lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;
3045 lpProcTable->lpWSPSendTo = WSPSendTo;
3046 lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
3047 lpProcTable->lpWSPShutdown = WSPShutdown;
3048 lpProcTable->lpWSPSocket = WSPSocket;
3049 lpProcTable->lpWSPStringToAddress = WSPStringToAddress;
3050 lpWSPData->wVersion = MAKEWORD(2, 2);
3051 lpWSPData->wHighVersion = MAKEWORD(2, 2);
3052 /* Save CatalogEntryId for all upcalls */
3053 CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
3054 }
3055
3056 TRACE("Status (%d).\n", Status);
3057 return Status;
3058}
3059
3060
3061INT
3062WSPAPI
3064 IN DWORD dwAddressLength,
3065 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
3066 OUT LPWSTR lpszAddressString,
3067 IN OUT LPDWORD lpdwAddressStringLength,
3068 OUT LPINT lpErrno)
3069{
3070 SIZE_T size;
3071 WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
3072 WCHAR *p;
3073
3074 if (!lpsaAddress || !lpszAddressString || !lpdwAddressStringLength)
3075 {
3076 if (lpErrno) *lpErrno = WSAEFAULT;
3077 return SOCKET_ERROR;
3078 }
3079
3080 switch (lpsaAddress->sa_family)
3081 {
3082 case AF_INET:
3083 if (dwAddressLength < sizeof(SOCKADDR_IN))
3084 {
3085 if (lpErrno) *lpErrno = WSAEINVAL;
3086 return SOCKET_ERROR;
3087 }
3089 L"%u.%u.%u.%u:%u",
3090 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 24 & 0xff),
3091 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 16 & 0xff),
3092 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 8 & 0xff),
3093 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) & 0xff),
3094 ntohs(((SOCKADDR_IN *)lpsaAddress)->sin_port));
3095
3096 p = wcschr(buffer, L':');
3097 if (!((SOCKADDR_IN *)lpsaAddress)->sin_port)
3098 {
3099 *p = 0;
3100 }
3101 break;
3102 default:
3103 if (lpErrno) *lpErrno = WSAEINVAL;
3104 return SOCKET_ERROR;
3105 }
3106
3107 size = wcslen(buffer) + 1;
3108
3109 if (*lpdwAddressStringLength < size)
3110 {
3111 *lpdwAddressStringLength = size;
3112 if (lpErrno) *lpErrno = WSAEFAULT;
3113 return SOCKET_ERROR;
3114 }
3115
3116 *lpdwAddressStringLength = size;
3117 wcscpy(lpszAddressString, buffer);
3118 return 0;
3119}
3120
3121INT
3122WSPAPI
3125 IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
3126 OUT LPSOCKADDR lpAddress,
3127 IN OUT LPINT lpAddressLength,
3128 OUT LPINT lpErrno)
3129{
3130 int numdots = 0;
3131 USHORT port;
3132 LONG inetaddr = 0, ip_part;
3133 LPWSTR *bp = NULL;
3135
3136 if (!lpAddressLength || !lpAddress || !AddressString)
3137 {
3138 if (lpErrno) *lpErrno = WSAEINVAL;
3139 return SOCKET_ERROR;
3140 }
3141
3142 sockaddr = (SOCKADDR_IN *)lpAddress;
3143
3144 /* Set right address family */
3145 if (lpProtocolInfo != NULL)
3146 {
3147 sockaddr->sin_family = lpProtocolInfo->iAddressFamily;
3148 }
3149 else
3150 {
3151 sockaddr->sin_family = AddressFamily;
3152 }
3153
3154 /* Report size */
3155 if (AddressFamily == AF_INET)
3156 {
3157 if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN))
3158 {
3159 if (lpErrno) *lpErrno = WSAEFAULT;
3160 }
3161 else
3162 {
3163 // translate ip string to ip
3164
3165 /* Get ip number */
3166 bp = &AddressString;
3167 inetaddr = 0;
3168
3169 while (*bp < &AddressString[wcslen(AddressString)])
3170 {
3171 ip_part = wcstol(*bp, bp, 10);
3172 /* ip part number should be in range 0-255 */
3173 if (ip_part < 0 || ip_part > 255)
3174 {
3175 if (lpErrno) *lpErrno = WSAEINVAL;
3176 return SOCKET_ERROR;
3177 }
3178 inetaddr = (inetaddr << 8) + ip_part;
3179 /* we end on string end or port separator */
3180 if ((*bp)[0] == 0 || (*bp)[0] == L':')
3181 break;
3182 /* ip parts are dot separated. verify it */
3183 if ((*bp)[0] != L'.')
3184 {
3185 if (lpErrno) *lpErrno = WSAEINVAL;
3186 return SOCKET_ERROR;
3187 }
3188 /* count the dots */
3189 numdots++;
3190 /* move over the dot to next ip part */
3191 (*bp)++;
3192 }
3193
3194 /* check dots count */
3195 if (numdots != 3)
3196 {
3197 if (lpErrno) *lpErrno = WSAEINVAL;
3198 return SOCKET_ERROR;
3199 }
3200
3201 /* Get port number */
3202 if ((*bp)[0] == L':')
3203 {
3204 /* move over the column to port part */
3205 (*bp)++;
3206 /* next char should be numeric */
3207 if ((*bp)[0] < L'0' || (*bp)[0] > L'9')
3208 {
3209 if (lpErrno) *lpErrno = WSAEINVAL;
3210 return SOCKET_ERROR;
3211 }
3212 port = wcstol(*bp, bp, 10);
3213 }
3214 else
3215 {
3216 port = 0;
3217 }
3218
3219 if (lpErrno) *lpErrno = NO_ERROR;
3220 /* rest sockaddr.sin_addr.s_addr
3221 for we need to be sure it is zero when we come to while */
3222 *lpAddressLength = sizeof(*sockaddr);
3223 memset(lpAddress, 0, sizeof(*sockaddr));
3224 sockaddr->sin_family = AF_INET;
3225 sockaddr->sin_addr.s_addr = inetaddr;
3226 sockaddr->sin_port = port;
3227 }
3228 }
3229
3230 if (lpErrno && !*lpErrno)
3231 {
3232 return 0;
3233 }
3234
3235 return SOCKET_ERROR;
3236}
3237
3238/*
3239 * FUNCTION: Cleans up service provider for a client
3240 * ARGUMENTS:
3241 * lpErrno = Address of buffer for error information
3242 * RETURNS:
3243 * 0 if successful, or SOCKET_ERROR if not
3244 */
3245INT
3246WSPAPI
3248
3249{
3250 TRACE("Leaving.\n");
3251
3252 if (lpErrno) *lpErrno = NO_ERROR;
3253
3254 return 0;
3255}
3256
3257VOID
3258NTAPI
3262{
3264
3265 Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
3267}
3268
3269int
3271 ULONG AfdInformationClass,
3272 PBOOLEAN Boolean OPTIONAL,
3274 PLARGE_INTEGER LargeInteger OPTIONAL,
3275 LPWSAOVERLAPPED Overlapped OPTIONAL,
3277{
3278 PIO_STATUS_BLOCK IOSB;
3279 IO_STATUS_BLOCK DummyIOSB;
3280 AFD_INFO InfoData;
3282 PAFDAPCCONTEXT APCContext;
3283 PIO_APC_ROUTINE APCFunction;
3284 HANDLE Event = NULL;
3286
3289 NULL,
3291 FALSE);
3292
3293 if( !NT_SUCCESS(Status) )
3294 return SOCKET_ERROR;
3295
3296 /* Set Info Class */
3297 InfoData.InformationClass = AfdInformationClass;
3298
3299 /* Verify if we should use APC */
3300 if (Overlapped == NULL)
3301 {
3302 /* Not using Overlapped structure, so use normal blocking on event */
3303 APCContext = NULL;
3304 APCFunction = NULL;
3305 Event = SockEvent;
3306 IOSB = &DummyIOSB;
3307 }
3308 else
3309 {
3310 /* Overlapped request for non overlapped opened socket */
3311 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3312 {
3313 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3314 NtClose( SockEvent );
3315 return 0;
3316 }
3317 if (CompletionRoutine == NULL)
3318 {
3319 /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
3320 APCContext = (PAFDAPCCONTEXT)Overlapped;
3321 APCFunction = NULL;
3322 Event = Overlapped->hEvent;
3323 }
3324 else
3325 {
3326 /* Using Overlapped Structure and a Completition Routine, so use an APC */
3327 APCFunction = &AfdInfoAPC; // should be a private io completition function inside us
3328 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
3329 if (!APCContext)
3330 {
3331 ERR("Not enough memory for APC Context\n");
3332 NtClose( SockEvent );
3333 return WSAEFAULT;
3334 }
3336 APCContext->lpOverlapped = Overlapped;
3337 APCContext->lpSocket = Socket;
3338 }
3339
3340 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3341 }
3342
3343 IOSB->Status = STATUS_PENDING;
3344
3345 /* Send IOCTL */
3347 Event,
3348 APCFunction,
3349 APCContext,
3350 IOSB,
3352 &InfoData,
3353 sizeof(InfoData),
3354 &InfoData,
3355 sizeof(InfoData));
3356
3357 /* Wait for return */
3358 if (Status == STATUS_PENDING && Overlapped == NULL)
3359 {
3361 Status = IOSB->Status;
3362 }
3363
3364 NtClose( SockEvent );
3365
3366 TRACE("Status %x Information %d\n", Status, IOSB->Information);
3367
3368 if (Status == STATUS_PENDING)
3369 {
3370 TRACE("Leaving (Pending)\n");
3371 return WSA_IO_PENDING;
3372 }
3373
3374 if (Status != STATUS_SUCCESS)
3375 return SOCKET_ERROR;
3376
3377 /* Return Information */
3378 if (Ulong != NULL)
3379 {
3380 *Ulong = InfoData.Information.Ulong;
3381 }
3382 if (LargeInteger != NULL)
3383 {
3384 *LargeInteger = InfoData.Information.LargeInteger;
3385 }
3386 if (Boolean != NULL)
3387 {
3388 *Boolean = InfoData.Information.Boolean;
3389 }
3390
3391 return NO_ERROR;
3392
3393}
3394
3395
3396int
3398 ULONG AfdInformationClass,
3399 PBOOLEAN Boolean OPTIONAL,
3401 PLARGE_INTEGER LargeInteger OPTIONAL,
3402 LPWSAOVERLAPPED Overlapped OPTIONAL,
3404{
3405 PIO_STATUS_BLOCK IOSB;
3406 IO_STATUS_BLOCK DummyIOSB;
3407 AFD_INFO InfoData;
3409 PAFDAPCCONTEXT APCContext;
3410 PIO_APC_ROUTINE APCFunction;
3411 HANDLE Event = NULL;
3413
3416 NULL,
3418 FALSE);
3419
3420 if( !NT_SUCCESS(Status) )
3421 return SOCKET_ERROR;
3422
3423 /* Set Info Class */
3424 InfoData.InformationClass = AfdInformationClass;
3425
3426 /* Set Information */
3427 if (Ulong != NULL)
3428 {
3429 InfoData.Information.Ulong = *Ulong;
3430 }
3431 if (LargeInteger != NULL)
3432 {
3433 InfoData.Information.LargeInteger = *LargeInteger;
3434 }
3435 if (Boolean != NULL)
3436 {
3437 InfoData.Information.Boolean = *Boolean;
3438 }
3439
3440 /* Verify if we should use APC */
3441 if (Overlapped == NULL)
3442 {
3443 /* Not using Overlapped structure, so use normal blocking on event */
3444 APCContext = NULL;
3445 APCFunction = NULL;
3446 Event = SockEvent;
3447 IOSB = &DummyIOSB;
3448 }
3449 else
3450 {
3451 /* Overlapped request for non overlapped opened socket */
3452 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3453 {
3454 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3455 NtClose( SockEvent );
3456 return 0;
3457 }
3458 if (CompletionRoutine == NULL)
3459 {
3460 /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
3461 APCContext = (PAFDAPCCONTEXT)Overlapped;
3462 APCFunction = NULL;
3463 Event = Overlapped->hEvent;
3464 }
3465 else
3466 {
3467 /* Using Overlapped Structure and a Completition Routine, so use an APC */
3468 APCFunction = &AfdInfoAPC; // should be a private io completition function inside us
3469 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
3470 if (!APCContext)
3471 {
3472 ERR("Not enough memory for APC Context\n");
3473 NtClose( SockEvent );
3474 return WSAEFAULT;
3475 }
3477 APCContext->lpOverlapped = Overlapped;
3478 APCContext->lpSocket = Socket;
3479 }
3480
3481 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3482 }
3483
3484 IOSB->Status = STATUS_PENDING;
3485
3486 /* Send IOCTL */
3488 Event,
3489 APCFunction,
3490 APCContext,
3491 IOSB,
3493 &InfoData,
3494 sizeof(InfoData),
3495 NULL,
3496 0);
3497
3498 /* Wait for return */
3499 if (Status == STATUS_PENDING && Overlapped == NULL)
3500 {
3502 Status = IOSB->Status;
3503 }
3504
3505 NtClose( SockEvent );
3506
3507 TRACE("Status %x Information %d\n", Status, IOSB->Information);
3508
3509 if (Status == STATUS_PENDING)
3510 {
3511 TRACE("Leaving (Pending)\n");
3512 return WSA_IO_PENDING;
3513 }
3514
3516
3517}
3518
3521{
3522 PSOCKET_INFORMATION CurrentSocket;
3523
3525
3526 CurrentSocket = SocketListHead;
3527 while (CurrentSocket)
3528 {
3529 if (CurrentSocket->Handle == Handle)
3530 {
3532 return CurrentSocket;
3533 }
3534
3535 CurrentSocket = CurrentSocket->NextSocket;
3536 }
3537
3539
3540 return NULL;
3541}
3542
3544{
3545 IO_STATUS_BLOCK IOSB;
3546 SOCKET_CONTEXT ContextData;
3549
3552 NULL,
3554 FALSE);
3555
3556 if( !NT_SUCCESS(Status) )
3557 return SOCKET_ERROR;
3558
3559 /* Create Context */
3560 ContextData.SharedData = *Socket->SharedData;
3561 ContextData.SizeOfHelperData = 0;
3562 RtlCopyMemory (&ContextData.LocalAddress,
3563 Socket->LocalAddress,
3565 RtlCopyMemory (&ContextData.RemoteAddress,
3566 Socket->RemoteAddress,
3568
3569 /* Send IOCTL */
3571 SockEvent,
3572 NULL,
3573 NULL,
3574 &IOSB,
3576 &ContextData,
3577 sizeof(ContextData),
3578 NULL,
3579 0);
3580
3581 /* Wait for Completion */
3582 if (Status == STATUS_PENDING)
3583 {
3585 Status = IOSB.Status;
3586 }
3587
3588 NtClose( SockEvent );
3589
3591}
3592
3594{
3595 HANDLE hAsyncThread;
3596 DWORD AsyncThreadId;
3597 HANDLE AsyncEvent;
3600
3601 /* Check if the Thread Already Exists */
3603 {
3605 return TRUE;
3606 }
3607
3608 /* Create the Completion Port */
3610 {
3613 NULL,
3614 2); // Allow 2 threads only
3615 if (!NT_SUCCESS(Status))
3616 {
3617 ERR("Failed to create completion port: 0x%08x\n", Status);
3618 return FALSE;
3619 }
3620 /* Protect Handle */
3621 HandleFlags.ProtectFromClose = TRUE;
3622 HandleFlags.Inherit = FALSE;
3624 ObjectHandleFlagInformation,
3625 &HandleFlags,
3626 sizeof(HandleFlags));
3627 }
3628
3629 /* Create the Async Event */
3630 Status = NtCreateEvent(&AsyncEvent,
3632 NULL,
3634 FALSE);
3635
3636 /* Create the Async Thread */
3637 hAsyncThread = CreateThread(NULL,
3638 0,
3640 NULL,
3641 0,
3642 &AsyncThreadId);
3643
3644 /* Close the Handle */
3645 NtClose(hAsyncThread);
3646
3647 /* Increase the Reference Count */
3649 return TRUE;
3650}
3651
3652ULONG
3653NTAPI
3655{
3656 PVOID AsyncContext;
3657 PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine;
3658 IO_STATUS_BLOCK IOSB;
3660
3661 /* Make the Thread Higher Priority */
3663
3664 /* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */
3665 do
3666 {
3668 (PVOID*)&AsyncCompletionRoutine,
3669 &AsyncContext,
3670 &IOSB,
3671 NULL);
3672 /* Call the Async Function */
3673 if (NT_SUCCESS(Status))
3674 {
3675 (*AsyncCompletionRoutine)(AsyncContext, &IOSB);
3676 }
3677 else
3678 {
3679 /* It Failed, sleep for a second */
3680 Sleep(1000);
3681 }
3682 } while ((Status != STATUS_TIMEOUT));
3683
3684 /* The Thread has Ended */
3685 return 0;
3686}
3687
3689{
3690 UNICODE_STRING AfdHelper;
3692 IO_STATUS_BLOCK IoSb;
3693 FILE_COMPLETION_INFORMATION CompletionInfo;
3695
3696 /* First, make sure we're not already initialized */
3698 {
3699 return TRUE;
3700 }
3701
3702 /* Set up Handle Name and Object */
3703 RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" );
3705 &AfdHelper,
3707 NULL,
3708 NULL);
3709
3710 /* Open the Handle to AFD */
3714 &IoSb,
3715 NULL,
3716 0,
3719 0,
3720 NULL,
3721 0);
3722
3723 /*
3724 * Now Set up the Completion Port Information
3725 * This means that whenever a Poll is finished, the routine will be executed
3726 */
3727 CompletionInfo.Port = SockAsyncCompletionPort;
3728 CompletionInfo.Key = SockAsyncSelectCompletionRoutine;
3730 &IoSb,
3731 &CompletionInfo,
3732 sizeof(CompletionInfo),
3734
3735
3736 /* Protect the Handle */
3737 HandleFlags.ProtectFromClose = TRUE;
3738 HandleFlags.Inherit = FALSE;
3740 ObjectHandleFlagInformation,
3741 &HandleFlags,
3742 sizeof(HandleFlags));
3743
3744
3745 /* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */
3747 return TRUE;
3748}
3749
3751{
3752
3753 PASYNC_DATA AsyncData = Context;
3754 PSOCKET_INFORMATION Socket;
3755 ULONG x;
3756
3757 /* Get the Socket */
3758 Socket = AsyncData->ParentSocket;
3759
3760 /* Check if the Sequence Number Changed behind our back */
3761 if (AsyncData->SequenceNumber != Socket->SharedData->SequenceNumber )
3762 {
3763 return;
3764 }
3765
3766 /* Check we were manually called b/c of a failure */
3768 {
3769 /* FIXME: Perform Upcall */
3770 return;
3771 }
3772
3773 for (x = 1; x; x<<=1)
3774 {
3775 switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x)
3776 {
3777 case AFD_EVENT_RECEIVE:
3778 if (0 != (Socket->SharedData->AsyncEvents & FD_READ) &&
3779 0 == (Socket->SharedData->AsyncDisabledEvents & FD_READ))
3780 {
3781 /* Make the Notification */
3783 Socket->SharedData->wMsg,
3784 Socket->Handle,
3786 /* Disable this event until the next read(); */
3788 }
3789 break;
3790
3792 if (0 != (Socket->SharedData->AsyncEvents & FD_OOB) &&
3793 0 == (Socket->SharedData->AsyncDisabledEvents & FD_OOB))
3794 {
3795 /* Make the Notification */
3797 Socket->SharedData->wMsg,
3798 Socket->Handle,
3800 /* Disable this event until the next read(); */
3802 }
3803 break;
3804
3805 case AFD_EVENT_SEND:
3806 if (0 != (Socket->SharedData->AsyncEvents & FD_WRITE) &&
3807 0 == (Socket->SharedData->AsyncDisabledEvents & FD_WRITE))
3808 {
3809 /* Make the Notification */
3811 Socket->SharedData->wMsg,
3812 Socket->Handle,
3814 /* Disable this event until the next write(); */
3816 }
3817 break;
3818
3819 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
3820 case AFD_EVENT_CONNECT:
3822 if (0 != (Socket->SharedData->AsyncEvents & FD_CONNECT) &&
3823 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CONNECT))
3824 {
3825 /* Make the Notification */
3827 Socket->SharedData->wMsg,
3828 Socket->Handle,
3830 /* Disable this event forever; */
3832 }
3833 break;
3834
3835 case AFD_EVENT_ACCEPT:
3836 if (0 != (Socket->SharedData->AsyncEvents & FD_ACCEPT) &&
3837 0 == (Socket->SharedData->AsyncDisabledEvents & FD_ACCEPT))
3838 {
3839 /* Make the Notification */
3841 Socket->SharedData->wMsg,
3842 Socket->Handle,
3844 /* Disable this event until the next accept(); */
3846 }
3847 break;
3848
3850 case AFD_EVENT_ABORT:
3851 case AFD_EVENT_CLOSE:
3852 if (0 != (Socket->SharedData->AsyncEvents & FD_CLOSE) &&
3853 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CLOSE))
3854 {
3855 /* Make the Notification */
3857 Socket->SharedData->wMsg,
3858 Socket->Handle,
3860 /* Disable this event forever; */
3862 }
3863 break;
3864 /* FIXME: Support QOS */
3865 }
3866 }
3867
3868 /* Check if there are any events left for us to check */
3869 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
3870 {
3871 return;
3872 }
3873
3874 /* Keep Polling */
3875 SockProcessAsyncSelect(Socket, AsyncData);
3876 return;
3877}
3878
3880{
3881
3882 ULONG lNetworkEvents;
3884
3885 /* Set up the Async Data Event Info */
3886 AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF;
3887 AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF;
3888 AsyncData->AsyncSelectInfo.HandleCount = 1;
3889 AsyncData->AsyncSelectInfo.Exclusive = TRUE;
3890 AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle;
3891 AsyncData->AsyncSelectInfo.Handles[0].Events = 0;
3892
3893 /* Remove unwanted events */
3894 lNetworkEvents = Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents);
3895
3896 /* Set Events to wait for */
3897 if (lNetworkEvents & FD_READ)
3898 {
3900 }
3901
3902 if (lNetworkEvents & FD_WRITE)
3903 {
3905 }
3906
3907 if (lNetworkEvents & FD_OOB)
3908 {
3910 }
3911
3912 if (lNetworkEvents & FD_ACCEPT)
3913 {
3915 }
3916
3917 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
3918 if (lNetworkEvents & FD_CONNECT)
3919 {
3921 }
3922
3923 if (lNetworkEvents & FD_CLOSE)
3924 {
3926 }
3927
3928 if (lNetworkEvents & FD_QOS)
3929 {
3931 }
3932
3933 if (lNetworkEvents & FD_GROUP_QOS)
3934 {
3936 }
3937
3938 /* Send IOCTL */
3940 NULL,
3941 NULL,
3942 AsyncData,
3943 &AsyncData->IoStatusBlock,
3945 &AsyncData->AsyncSelectInfo,
3946 sizeof(AsyncData->AsyncSelectInfo),
3947 &AsyncData->AsyncSelectInfo,
3948 sizeof(AsyncData->AsyncSelectInfo));
3949
3950 /* I/O Manager Won't call the completion routine, let's do it manually */
3951 if (NT_SUCCESS(Status))
3952 {
3953 return;
3954 }
3955 else
3956 {
3957 AsyncData->IoStatusBlock.Status = Status;
3958 SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock);
3959 }
3960}
3961
3963{
3964 PASYNC_DATA AsyncData = Context;
3965 BOOL FreeContext = TRUE;
3966 PSOCKET_INFORMATION Socket;
3967
3968 /* Get the Socket */
3969 Socket = AsyncData->ParentSocket;
3970
3971 /* If someone closed it, stop the function */
3972 if (Socket->SharedData->State != SocketClosed)
3973 {
3974 /* Check if the Sequence Number changed by now, in which case quit */
3975 if (AsyncData->SequenceNumber == Socket->SharedData->SequenceNumber)
3976 {
3977 /* Do the actual select, if needed */
3978 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)))
3979 {
3980 SockProcessAsyncSelect(Socket, AsyncData);
3981 FreeContext = FALSE;
3982 }
3983 }
3984 }
3985
3986 /* Free the Context */
3987 if (FreeContext)
3988 {
3989 HeapFree(GetProcessHeap(), 0, AsyncData);
3990 }
3991
3992 return;
3993}
3994
3995VOID
3997 IN ULONG Event)
3998{
3999 PASYNC_DATA AsyncData;
4000
4001 /* Make sure the event is actually disabled */
4002 if (!(Socket->SharedData->AsyncDisabledEvents & Event))
4003 {
4004 return;
4005 }
4006
4007 /* Re-enable it */
4008 Socket->SharedData->AsyncDisabledEvents &= ~Event;
4009
4010 /* Return if no more events are being polled */
4011 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
4012 {
4013 return;
4014 }
4015
4016 /* Wait on new events */
4017 AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(ASYNC_DATA));
4018 if (!AsyncData) return;
4019
4020 /* Create the Asynch Thread if Needed */
4022
4023 /* Increase the sequence number to stop anything else */
4024 Socket->SharedData->SequenceNumber++;
4025
4026 /* Set up the Async Data */
4027 AsyncData->ParentSocket = Socket;
4028 AsyncData->SequenceNumber = Socket->SharedData->SequenceNumber;
4029
4030 /* Begin Async Select by using I/O Completion */
4033 AsyncData,
4034 0,
4035 0);
4036
4037 /* All done */
4038 return;
4039}
4040
4041BOOL
4042WINAPI
4046{
4047
4048 switch (dwReason)
4049 {
4050 case DLL_PROCESS_ATTACH:
4051
4052 TRACE("Loading MSAFD.DLL \n");
4053
4054 /* Don't need thread attach notifications
4055 so disable them to improve performance */
4056 DisableThreadLibraryCalls(hInstDll);
4057
4058 /* List of DLL Helpers */
4060
4061 /* Heap to use when allocating */
4063
4064 /* Initialize the lock that protects our socket list */
4066
4067 TRACE("MSAFD.DLL has been loaded\n");
4068
4069 break;
4070
4071 case DLL_THREAD_ATTACH:
4072 break;
4073
4074 case DLL_THREAD_DETACH:
4075 break;
4076
4077 case DLL_PROCESS_DETACH:
4078
4079 /* Delete the socket list lock */
4081
4082 break;
4083 }
4084
4085 TRACE("DllMain of msafd.dll (leaving)\n");
4086
4087 return TRUE;
4088}
4089
4090/* 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:141
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define HandleToUlong(h)
Definition: basetsd.h:79
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_PENDING
Definition: d3dkmdt.h:43
#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
#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
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:3063
int WSPAPI WSPListen(SOCKET Handle, int Backlog, LPINT lpErrno)
Definition: dllmain.c:981
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:2785
VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:3750
INT WSPAPI WSPCleanup(OUT LPINT lpErrno)
Definition: dllmain.c:3247
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:3270
int WSPAPI WSPConnect(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
Definition: dllmain.c:1830
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:2609
HANDLE SockAsyncCompletionPort
Definition: dllmain.c:28
INT WSPAPI WSPBind(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPINT lpErrno)
Definition: dllmain.c:846
BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
Definition: dllmain.c:3593
VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
Definition: dllmain.c:3879
DWORD CatalogEntryId
Definition: dllmain.c:21
LIST_ENTRY SockHelpersListHead
Definition: dllmain.c:25
HANDLE SockAsyncHelperAfdHandle
Definition: dllmain.c:27
DWORD GetCurrentTimeInSeconds(VOID)
Definition: dllmain.c:1417
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3520
INT WSPAPI WSPGetPeerName(IN SOCKET s, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
Definition: dllmain.c:2258
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:1065
int CreateContext(PSOCKET_INFORMATION Socket)
Definition: dllmain.c:3543
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:3962
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:3397
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:3654
int WSPAPI WSPShutdown(SOCKET Handle, int HowTo, LPINT lpErrno)
Definition: dllmain.c:2076
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:3123
_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:2998
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:2361
ULONG SockAsyncThreadRefCount
Definition: dllmain.c:26
INT WSPAPI WSPCloseSocket(IN SOCKET Handle, OUT LPINT lpErrno)
Definition: dllmain.c:623
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:1434
SOCKET WSPAPI WSPSocket(int AddressFamily, int SocketType, int Protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)
Definition: dllmain.c:48
VOID NTAPI AfdInfoAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
Definition: dllmain.c:3259
INT WSPAPI WSPGetSockName(IN SOCKET Handle, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
Definition: dllmain.c:2156
BOOLEAN SockAsyncSelectCalled
Definition: dllmain.c:29
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3996
WSPUPCALLTABLE Upcalls
Definition: dllmain.c:20
BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID)
Definition: dllmain.c:3688
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
enum _SOCKET_STATE SOCKET_STATE
FORCEINLINE DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes)
Definition: msafd.h:546
struct _AFDAPCCONTEXT * PAFDAPCCONTEXT
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:542
USHORT port
Definition: uri.c:228
#define swprintf
Definition: precomp.h:40
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
#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 int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
@ 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
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
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
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
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG)
Definition: largeint.c:31
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
#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
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static PLARGE_INTEGER Time
Definition: time.c:105
int notify
Definition: msacm.c:1366
#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 _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