ReactOS 0.4.17-dev-934-g091855f
dllmain.c File Reference
#include <msafd.h>
#include <winuser.h>
#include <wchar.h>
Include dependency graph for dllmain.c:

Go to the source code of this file.

Functions

SOCKET WSPAPI WSPSocket (int AddressFamily, int SocketType, int Protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)
 
INT WSPAPI WSPDuplicateSocket (IN SOCKET Handle, IN DWORD dwProcessId, OUT LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPINT lpErrno)
 
INT TranslateNtStatusError (NTSTATUS Status)
 
VOID MsafdWaitForAlert (_In_ HANDLE hObject)
 
INT WSPAPI WSPCloseSocket (IN SOCKET Handle, OUT LPINT lpErrno)
 
INT WSPAPI WSPBind (SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPINT lpErrno)
 
int WSPAPI WSPListen (SOCKET Handle, int Backlog, LPINT lpErrno)
 
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)
 
DWORD GetCurrentTimeInSeconds (VOID)
 
_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)
 
BOOL WSPAPI WSPAcceptEx (_In_ SOCKET sListenSocket, _In_ SOCKET sAcceptSocket, _Out_ PVOID lpOutputBuffer, _In_ DWORD dwReceiveDataLength, _In_ DWORD dwLocalAddressLength, _In_ DWORD dwRemoteAddressLength, _Out_ LPDWORD lpdwBytesReceived, _Inout_ LPOVERLAPPED lpOverlapped)
 
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)
 
static VOID NTAPI MsafdConnectAPC (_In_ PVOID ApcContext, _In_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG Reserved)
 
int WSPAPI WSPConnect (SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
 
BOOL WSPAPI WSPConnectEx (_In_ SOCKET Handle, _In_ const struct sockaddr *SocketAddress, _In_ int SocketAddressLength, _In_ PVOID lpSendBuffer, _In_ DWORD dwSendDataLength, _Out_ LPDWORD lpdwBytesSent, _Inout_ LPOVERLAPPED lpOverlapped)
 
int WSPAPI WSPShutdown (SOCKET Handle, int HowTo, LPINT lpErrno)
 
INT WSPAPI WSPGetSockName (IN SOCKET Handle, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
 
INT WSPAPI WSPGetPeerName (IN SOCKET s, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
 
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)
 
INT WSPAPI WSPGetSockOpt (IN SOCKET Handle, IN INT Level, IN INT OptionName, OUT CHAR FAR *OptionValue, IN OUT LPINT OptionLength, OUT LPINT lpErrno)
 
static INT NTAPI MsafdUpdateConnectionContext (_In_ SOCKET Handle, _Out_ LPINT lpErrno)
 
INT WSPAPI WSPSetSockOpt (IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen, OUT LPINT lpErrno)
 
_Must_inspect_result_ int WSPAPI WSPStartup (_In_ WORD wVersionRequested, _In_ LPWSPDATA lpWSPData, _In_ LPWSAPROTOCOL_INFOW lpProtocolInfo, _In_ WSPUPCALLTABLE UpcallTable, _Out_ LPWSPPROC_TABLE lpProcTable)
 
INT WSPAPI WSPAddressToString (IN LPSOCKADDR lpsaAddress, IN DWORD dwAddressLength, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPWSTR lpszAddressString, IN OUT LPDWORD lpdwAddressStringLength, OUT LPINT lpErrno)
 
INT WSPAPI WSPStringToAddress (IN LPWSTR AddressString, IN INT AddressFamily, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPSOCKADDR lpAddress, IN OUT LPINT lpAddressLength, OUT LPINT lpErrno)
 
INT WSPAPI WSPCleanup (OUT LPINT lpErrno)
 
static VOID NTAPI MsafdInfoAPC (_In_ PVOID ApcContext, _In_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG Reserved)
 
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)
 
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)
 
PSOCKET_INFORMATION GetSocketStructure (SOCKET Handle)
 
int CreateContext (PSOCKET_INFORMATION Socket)
 
BOOLEAN SockCreateOrReferenceAsyncThread (VOID)
 
ULONG NTAPI SockAsyncThread (PVOID ThreadParam)
 
BOOLEAN SockGetAsyncSelectHelperAfdHandle (VOID)
 
VOID SockAsyncSelectCompletionRoutine (PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
 
VOID SockProcessAsyncSelect (PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
 
VOID SockProcessQueuedAsyncSelect (PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
 
VOID SockReenableAsyncSelectEvent (IN PSOCKET_INFORMATION Socket, IN ULONG Event)
 
BOOL WINAPI DllMain (HANDLE hInstDll, ULONG dwReason, PVOID Reserved)
 

Variables

HANDLE GlobalHeap
 
WSPUPCALLTABLE Upcalls
 
DWORD CatalogEntryId
 
LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest
 
PSOCKET_INFORMATION SocketListHead = NULL
 
CRITICAL_SECTION SocketListLock
 
LIST_ENTRY SockHelpersListHead = { NULL, NULL }
 
ULONG SockAsyncThreadRefCount
 
HANDLE SockAsyncHelperAfdHandle
 
HANDLE SockAsyncCompletionPort = NULL
 
BOOLEAN SockAsyncSelectCalled
 

Function Documentation

◆ CreateContext()

int CreateContext ( PSOCKET_INFORMATION  Socket)

Definition at line 3983 of file dllmain.c.

3984{
3985 IO_STATUS_BLOCK IOSB;
3986 SOCKET_CONTEXT ContextData;
3989
3992 NULL,
3994 FALSE);
3995
3996 if( !NT_SUCCESS(Status) )
3997 return SOCKET_ERROR;
3998
3999 /* Create Context */
4000 ContextData.SharedData = *Socket->SharedData;
4001 ContextData.SizeOfHelperData = 0;
4002 RtlCopyMemory (&ContextData.LocalAddress,
4003 Socket->LocalAddress,
4005 RtlCopyMemory (&ContextData.RemoteAddress,
4006 Socket->RemoteAddress,
4008
4009 /* Send IOCTL */
4011 SockEvent,
4012 NULL,
4013 NULL,
4014 &IOSB,
4016 &ContextData,
4017 sizeof(ContextData),
4018 NULL,
4019 0);
4020
4021 /* Wait for Completion */
4022 if (Status == STATUS_PENDING)
4023 {
4025 Status = IOSB.Status;
4026 }
4027
4028 NtClose( SockEvent );
4029
4031}
LONG NTSTATUS
Definition: precomp.h:26
#define NO_ERROR
Definition: dderror.h:5
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID MsafdWaitForAlert(_In_ HANDLE hObject)
Definition: dllmain.c:614
HANDLE SockEvent
Status
Definition: gdiplustypes.h:24
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3429
@ SynchronizationEvent
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
#define IOCTL_AFD_SET_CONTEXT
Definition: shared.h:319
#define STATUS_SUCCESS
Definition: shellext.h:65
SOCK_SHARED_INFO SharedData
Definition: msafd.h:68
SOCKADDR RemoteAddress
Definition: msafd.h:72
SOCKADDR LocalAddress
Definition: msafd.h:71
ULONG SizeOfHelperData
Definition: msafd.h:69
PSOCKADDR LocalAddress
Definition: msafd.h:52
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:47
PSOCKADDR RemoteAddress
Definition: msafd.h:53
SOCKET Handle
Definition: msafd.h:46
INT SizeOfLocalAddress
Definition: shared.h:388
INT SizeOfRemoteAddress
Definition: shared.h:389
#define STATUS_PENDING
Definition: telnetd.h:14
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define SOCKET_ERROR
Definition: winsock.h:327

Referenced by WSPSocket().

◆ DllMain()

BOOL WINAPI DllMain ( HANDLE  hInstDll,
ULONG  dwReason,
PVOID  Reserved 
)

Definition at line 4483 of file dllmain.c.

4486{
4487
4488 switch (dwReason)
4489 {
4490 case DLL_PROCESS_ATTACH:
4491
4492 TRACE("Loading MSAFD.DLL \n");
4493
4494 /* Don't need thread attach notifications
4495 so disable them to improve performance */
4496 DisableThreadLibraryCalls(hInstDll);
4497
4498 /* List of DLL Helpers */
4500
4501 /* Heap to use when allocating */
4503
4504 /* Initialize the lock that protects our socket list */
4506
4507 TRACE("MSAFD.DLL has been loaded\n");
4508
4509 break;
4510
4511 case DLL_THREAD_ATTACH:
4512 break;
4513
4514 case DLL_THREAD_DETACH:
4515 break;
4516
4517 case DLL_PROCESS_DETACH:
4518
4519 /* Delete the socket list lock */
4521
4522 break;
4523 }
4524
4525 TRACE("DllMain of msafd.dll (leaving)\n");
4526
4527 return TRUE;
4528}
DWORD dwReason
Definition: misc.cpp:135
#define TRUE
Definition: types.h:120
#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 DLL_THREAD_ATTACH
Definition: compat.h:132
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
LIST_ENTRY SockHelpersListHead
Definition: dllmain.c:25
HANDLE GlobalHeap
Definition: dllmain.c:19
CRITICAL_SECTION SocketListLock
Definition: dllmain.c:24
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define TRACE(s)
Definition: solgame.cpp:4
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:687
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

◆ GetCurrentTimeInSeconds()

DWORD GetCurrentTimeInSeconds ( VOID  )

Definition at line 1434 of file dllmain.c.

1435{
1436 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
1437 union
1438 {
1439 FILETIME ft;
1440 ULONGLONG ll;
1441 } u1970, Time;
1442
1444 SystemTimeToFileTime(&st1970, &u1970.ft);
1445 return (DWORD)((Time.ll - u1970.ll) / 10000000ULL);
1446}
w ll
Definition: byte_order.h:167
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:153
unsigned long DWORD
Definition: ntddk_ex.h:95
static PLARGE_INTEGER Time
Definition: time.c:37
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by MsafdConnectAPC(), WSPAccept(), WSPConnect(), and WSPGetSockOpt().

◆ GetSocketInformation()

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 at line 3712 of file dllmain.c.

3719{
3720 PIO_STATUS_BLOCK IOSB;
3721 IO_STATUS_BLOCK DummyIOSB;
3722 PAFD_INFO InfoData;
3724 PMSAFD_INFO_APC_CONTEXT APCContext;
3725 PIO_APC_ROUTINE APCFunction;
3726 HANDLE Event = NULL;
3728
3729 InfoData = HeapAlloc(GlobalHeap, 0, sizeof(*InfoData));
3730 if (!InfoData)
3731 return SOCKET_ERROR;
3732
3735 NULL,
3737 FALSE);
3738 if (!NT_SUCCESS(Status))
3739 {
3740 HeapFree(GlobalHeap, 0, InfoData);
3741 return SOCKET_ERROR;
3742 }
3743
3744 /* Set Info Class */
3745 InfoData->InformationClass = AfdInformationClass;
3746
3747 /* Verify if we should use APC */
3748 if (!Overlapped)
3749 {
3750 /* Not using Overlapped structure, so use normal blocking on event */
3751 APCContext = NULL;
3752 APCFunction = NULL;
3753 Event = SockEvent;
3754 IOSB = &DummyIOSB;
3755 }
3756 else
3757 {
3758 /* Overlapped request for non overlapped opened socket */
3759 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3760 {
3761 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3763 HeapFree(GlobalHeap, 0, InfoData);
3765 }
3766
3767 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
3768 if (!APCContext)
3769 {
3770 ERR("Not enough memory for APC Context\n");
3772 HeapFree(GlobalHeap, 0, InfoData);
3774 }
3776 APCContext->lpOverlapped = Overlapped;
3777 APCContext->lpInfoData = InfoData;
3778 APCFunction = &MsafdInfoAPC;
3779
3780 if (!CompletionRoutine)
3781 Event = Overlapped->hEvent;
3782
3783 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3784 }
3785
3786 IOSB->Status = STATUS_PENDING;
3787
3788 /* Send IOCTL */
3790 Event,
3791 APCFunction,
3792 APCContext,
3793 IOSB,
3795 InfoData,
3796 sizeof(*InfoData),
3797 InfoData,
3798 sizeof(*InfoData));
3799
3800 /* Wait for completion if not overlapped */
3801 if (!Overlapped && Status == STATUS_PENDING)
3802 {
3804 Status = IOSB->Status;
3805 }
3806
3807 TRACE("Status %lx\n", Status);
3808
3809 if (Status == STATUS_SUCCESS)
3810 {
3811 /* Return Information */
3812 if (Ulong != NULL)
3813 {
3814 *Ulong = InfoData->Information.Ulong;
3815 }
3816 if (LargeInteger != NULL)
3817 {
3818 *LargeInteger = InfoData->Information.LargeInteger;
3819 }
3820 if (Boolean != NULL)
3821 {
3822 *Boolean = InfoData->Information.Boolean;
3823 }
3824 }
3825
3827 if (!APCFunction)
3828 {
3829 /* When using APC, this will be freed by the APC function */
3830 HeapFree(GlobalHeap, 0, InfoData);
3831 }
3832
3833 return MsafdReturnWithErrno(Status, NULL, 0, NULL);
3834}
#define ERR(fmt,...)
Definition: precomp.h:57
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
static VOID NTAPI MsafdInfoAPC(_In_ PVOID ApcContext, _In_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG Reserved)
Definition: dllmain.c:3693
FORCEINLINE DWORD MsafdReturnWithErrno(_In_ NTSTATUS Status, _Out_opt_ LPINT Errno, _In_ DWORD Received, _Out_opt_ LPDWORD ReturnedBytes)
Definition: msafd.h:515
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:880
#define IOCTL_AFD_GET_INFO
Definition: shared.h:345
ULONG InformationClass
Definition: shared.h:29
ULONG Ulong
Definition: shared.h:31
union _AFD_INFO::@4118 Information
BOOLEAN Boolean
Definition: shared.h:33
LARGE_INTEGER LargeInteger
Definition: shared.h:32
PAFD_INFO lpInfoData
Definition: msafd.h:87
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
Definition: msafd.h:86
LPWSAOVERLAPPED lpOverlapped
Definition: msafd.h:85
DWORD CreateFlags
Definition: shared.h:410
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
unsigned long Ulong
Definition: utypes.h:42
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895

Referenced by WSPCloseSocket(), WSPIoctl(), WSPSetSockOpt(), and WSPSocket().

◆ GetSocketStructure()

PSOCKET_INFORMATION GetSocketStructure ( SOCKET  Handle)

Definition at line 3960 of file dllmain.c.

3961{
3962 PSOCKET_INFORMATION CurrentSocket;
3963
3965
3966 CurrentSocket = SocketListHead;
3967 while (CurrentSocket)
3968 {
3969 if (CurrentSocket->Handle == Handle)
3970 {
3972 return CurrentSocket;
3973 }
3974
3975 CurrentSocket = CurrentSocket->NextSocket;
3976 }
3977
3979
3980 return NULL;
3981}
PSOCKET_INFORMATION SocketListHead
Definition: dllmain.c:23
ULONG Handle
Definition: gdb_input.c:15
struct _SOCKET_INFORMATION * NextSocket
Definition: msafd.h:63
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by MsafdConnectAPC(), MsafdUpdateConnectionContext(), WSPAccept(), WSPAcceptEx(), WSPAsyncSelect(), WSPBind(), WSPCloseSocket(), WSPConnect(), WSPConnectEx(), WSPDuplicateSocket(), WSPEnumNetworkEvents(), WSPEventSelect(), WSPGetOverlappedResult(), WSPGetPeerName(), WSPGetSockName(), WSPGetSockOpt(), WSPIoctl(), WSPListen(), WSPRecv(), WSPRecvFrom(), WSPSelect(), WSPSend(), WSPSendTo(), WSPSetSockOpt(), and WSPShutdown().

◆ MsafdConnectAPC()

static VOID NTAPI MsafdConnectAPC ( _In_ PVOID  ApcContext,
_In_ PIO_STATUS_BLOCK  IoStatusBlock,
_In_ ULONG  Reserved 
)
static

Definition at line 1964 of file dllmain.c.

1968{
1970
1971 TRACE("MsafdConnectAPC(%p %lx %lx)\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information);
1972
1974 if (!Socket)
1975 {
1976 // FIXME: Socket is closed before this APC could run
1978 return;
1979 }
1980
1982 if (IoStatusBlock->Status == STATUS_SUCCESS)
1983 {
1984 Socket->SharedData->State = SocketConnected;
1985 Socket->TdiConnectionHandle = (HANDLE)IoStatusBlock->Information;
1987 }
1988
1989 /* Re-enable Async Event */
1991
1992 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
1994
1995 if (IoStatusBlock->Status == STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_CONNECT))
1996 {
1997 Socket->HelperData->WSHNotify(Socket->HelperContext,
1998 Socket->Handle,
1999 Socket->TdiAddressHandle,
2000 Socket->TdiConnectionHandle,
2002 }
2003 else if (IoStatusBlock->Status != STATUS_SUCCESS && (Socket->HelperEvents & WSH_NOTIFY_CONNECT_ERROR))
2004 {
2005 Socket->HelperData->WSHNotify(Socket->HelperContext,
2006 Socket->Handle,
2007 Socket->TdiAddressHandle,
2008 Socket->TdiConnectionHandle,
2010 }
2011
2013}
_In_ PIO_STATUS_BLOCK IoStatusBlock
Definition: dispmprt.h:608
DWORD GetCurrentTimeInSeconds(VOID)
Definition: dllmain.c:1434
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3960
INT TranslateNtStatusError(NTSTATUS Status)
Definition: dllmain.c:537
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:4436
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:727
@ SocketConnected
Definition: shared.h:378
_In_ PVOID Context
Definition: storport.h:2269
PWSH_NOTIFY WSHNotify
Definition: helpers.h:25
PVOID HelperContext
Definition: msafd.h:51
HANDLE TdiConnectionHandle
Definition: msafd.h:55
PHELPER_DATA HelperData
Definition: msafd.h:50
HANDLE TdiAddressHandle
Definition: msafd.h:54
DWORD HelperEvents
Definition: msafd.h:49
SOCKET_STATE State
Definition: shared.h:383
INT SocketLastError
Definition: shared.h:416
ULONG ConnectTime
Definition: shared.h:395
PVOID HANDLE
Definition: typedefs.h:73
#define FD_WRITE
Definition: winsock.h:400
#define FD_CONNECT
Definition: winsock.h:403
#define WSH_NOTIFY_CONNECT_ERROR
Definition: wsahelp.h:18
#define WSH_NOTIFY_CONNECT
Definition: wsahelp.h:12

Referenced by WSPConnect().

◆ MsafdInfoAPC()

static VOID NTAPI MsafdInfoAPC ( _In_ PVOID  ApcContext,
_In_ PIO_STATUS_BLOCK  IoStatusBlock,
_In_ ULONG  Reserved 
)
static

Definition at line 3693 of file dllmain.c.

3697{
3699
3700 TRACE("MsafdInfoAPC(%p %lx %lx)\n", ApcContext, IoStatusBlock->Status, IoStatusBlock->Information);
3701
3702 if (Context->lpCompletionRoutine)
3703 Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
3704
3705 /* Free IOCTL buffer */
3706 HeapFree(GlobalHeap, 0, Context->lpInfoData);
3707
3709}

Referenced by GetSocketInformation(), and SetSocketInformation().

◆ MsafdUpdateConnectionContext()

static INT NTAPI MsafdUpdateConnectionContext ( _In_ SOCKET  Handle,
_Out_ LPINT  lpErrno 
)
static

Definition at line 3105 of file dllmain.c.

3108{
3109 IO_STATUS_BLOCK DummyIOSB;
3110 PIO_STATUS_BLOCK IOSB = &DummyIOSB;
3112 SOCK_SHARED_INFO SharedData;
3113 AFD_TDI_HANDLE_DATA HandleData;
3116
3117 if (!Socket)
3118 {
3119 if (lpErrno) *lpErrno = WSAENOTSOCK;
3120 return SOCKET_ERROR;
3121 }
3122
3123 if (Socket->SharedData->State == SocketConnected)
3124 {
3125 return NO_ERROR;
3126 }
3127
3128 /* Get the socket context from AFD because when ConnectEx is used, this information is not updated. */
3131 NULL,
3133 FALSE);
3134 if (!NT_SUCCESS(Status))
3135 goto Quit;
3136
3138 SockEvent,
3139 NULL,
3140 NULL,
3141 IOSB,
3143 NULL,
3144 0,
3145 &SharedData,
3146 sizeof(SharedData));
3147
3148 if (Status == STATUS_PENDING)
3149 {
3151 Status = IOSB->Status;
3152 }
3153
3154 if (!NT_SUCCESS(Status))
3155 goto Quit;
3156
3158
3159 /* Get TDI handles from AFD */
3161 SockEvent,
3162 NULL,
3163 NULL,
3164 IOSB,
3166 &flags,
3167 sizeof(flags),
3168 &HandleData,
3169 sizeof(HandleData));
3170
3171 if (Status == STATUS_PENDING)
3172 {
3174 Status = IOSB->Status;
3175 }
3176
3177 /* Bail out if the socket was destroyed */
3178 if (!NT_SUCCESS(Status))
3179 goto Quit;
3180
3181 Socket->SharedData->State = SharedData.State;
3182
3183 if (SharedData.State == SocketConnected)
3184 {
3185 /* Socket is now connected, update usermode msafd socket structure, same as the end of WSPConnect */
3186 Socket->TdiConnectionHandle = HandleData.TdiConnectionHandle;
3187 Socket->TdiAddressHandle = HandleData.TdiAddressHandle;
3188 Socket->SharedData->ConnectTime = SharedData.ConnectTime;
3189
3190 /* Re-enable Async Event */
3192
3193 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
3195
3196 Socket->HelperData->WSHNotify(Socket->HelperContext,
3197 Socket->Handle,
3198 Socket->TdiAddressHandle,
3199 Socket->TdiConnectionHandle,
3201 }
3202
3204
3205Quit:
3206 if (Status == STATUS_SUCCESS)
3207 return NO_ERROR;
3208 if (lpErrno) *lpErrno = TranslateNtStatusError(Status);
3209 return SOCKET_ERROR;
3210}
GLbitfield flags
Definition: glext.h:7161
#define IOCTL_AFD_GET_TDI_HANDLES
Definition: shared.h:311
#define IOCTL_AFD_GET_CONTEXT
Definition: shared.h:317
#define AFD_CONNECTION_HANDLE
Definition: shared.h:178
#define AFD_ADDRESS_HANDLE
Definition: shared.h:177
HANDLE TdiConnectionHandle
Definition: shared.h:165
HANDLE TdiAddressHandle
Definition: shared.h:164
uint32_t ULONG
Definition: typedefs.h:59
#define WSAENOTSOCK
Definition: winerror.h:2854

Referenced by WSPSetSockOpt().

◆ MsafdWaitForAlert()

VOID MsafdWaitForAlert ( _In_ HANDLE  hObject)

Definition at line 614 of file dllmain.c.

616{
618
619 for (;;)
620 {
623 break;
624 }
625}
#define INFINITE
Definition: serial.h:102
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define WAIT_IO_COMPLETION
Definition: winbase.h:388
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by CreateContext(), GetSocketInformation(), MsafdUpdateConnectionContext(), SetSocketInformation(), WSPAccept(), WSPBind(), WSPCloseSocket(), WSPConnect(), WSPEnumNetworkEvents(), WSPEventSelect(), WSPGetPeerName(), WSPGetSockName(), WSPListen(), WSPRecv(), WSPRecvFrom(), WSPSelect(), WSPSend(), WSPSendTo(), and WSPShutdown().

◆ SetSocketInformation()

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 at line 3838 of file dllmain.c.

3845{
3846 PIO_STATUS_BLOCK IOSB;
3847 IO_STATUS_BLOCK DummyIOSB;
3848 PAFD_INFO InfoData;
3850 PMSAFD_INFO_APC_CONTEXT APCContext;
3851 PIO_APC_ROUTINE APCFunction;
3852 HANDLE Event = NULL;
3854
3855 InfoData = HeapAlloc(GlobalHeap, 0, sizeof(*InfoData));
3856 if (!InfoData)
3857 return SOCKET_ERROR;
3858
3861 NULL,
3863 FALSE);
3864 if (!NT_SUCCESS(Status))
3865 {
3866 HeapFree(GlobalHeap, 0, InfoData);
3867 return SOCKET_ERROR;
3868 }
3869
3870 /* Set Info Class */
3871 InfoData->InformationClass = AfdInformationClass;
3872
3873 /* Set Information */
3874 if (Ulong != NULL)
3875 {
3876 InfoData->Information.Ulong = *Ulong;
3877 }
3878 if (LargeInteger != NULL)
3879 {
3880 InfoData->Information.LargeInteger = *LargeInteger;
3881 }
3882 if (Boolean != NULL)
3883 {
3884 InfoData->Information.Boolean = *Boolean;
3885 }
3886
3887 /* Verify if we should use APC */
3888 if (!Overlapped)
3889 {
3890 /* Not using Overlapped structure, so use normal blocking on event */
3891 APCContext = NULL;
3892 APCFunction = NULL;
3893 Event = SockEvent;
3894 IOSB = &DummyIOSB;
3895 }
3896 else
3897 {
3898 /* Overlapped request for non overlapped opened socket */
3899 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3900 {
3901 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3903 HeapFree(GlobalHeap, 0, InfoData);
3905 }
3906
3907 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
3908 if (!APCContext)
3909 {
3910 ERR("Not enough memory for APC Context\n");
3912 HeapFree(GlobalHeap, 0, InfoData);
3914 }
3916 APCContext->lpOverlapped = Overlapped;
3917 APCContext->lpInfoData = InfoData;
3918 APCFunction = &MsafdInfoAPC;
3919
3920 if (!CompletionRoutine)
3921 Event = Overlapped->hEvent;
3922
3923 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3924 }
3925
3926 IOSB->Status = STATUS_PENDING;
3927
3928 /* Send IOCTL */
3930 Event,
3931 APCFunction,
3932 APCContext,
3933 IOSB,
3935 InfoData,
3936 sizeof(*InfoData),
3937 NULL,
3938 0);
3939
3940 /* Wait for completion if not overlapped */
3941 if (!Overlapped && Status == STATUS_PENDING)
3942 {
3944 Status = IOSB->Status;
3945 }
3946
3947 TRACE("Status %lx\n", Status);
3948
3950 if (!APCFunction)
3951 {
3952 /* When using APC, this will be freed by the APC function */
3953 HeapFree(GlobalHeap, 0, InfoData);
3954 }
3955
3956 return MsafdReturnWithErrno(Status, NULL, 0, NULL);
3957}
#define IOCTL_AFD_SET_INFO
Definition: shared.h:313

Referenced by WSPAsyncSelect(), WSPEventSelect(), WSPIoctl(), and WSPSetSockOpt().

◆ SockAsyncSelectCompletionRoutine()

VOID SockAsyncSelectCompletionRoutine ( PVOID  Context,
PIO_STATUS_BLOCK  IoStatusBlock 
)

Definition at line 4190 of file dllmain.c.

4191{
4192
4193 PASYNC_DATA AsyncData = Context;
4194 PSOCKET_INFORMATION Socket;
4195 ULONG x;
4196
4197 /* Get the Socket */
4198 Socket = AsyncData->ParentSocket;
4199
4200 /* Check if the Sequence Number Changed behind our back */
4201 if (AsyncData->SequenceNumber != Socket->SharedData->SequenceNumber )
4202 {
4203 return;
4204 }
4205
4206 /* Check we were manually called b/c of a failure */
4207 if (!NT_SUCCESS(IoStatusBlock->Status))
4208 {
4209 /* FIXME: Perform Upcall */
4210 return;
4211 }
4212
4213 for (x = 1; x; x<<=1)
4214 {
4215 switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x)
4216 {
4217 case AFD_EVENT_RECEIVE:
4218 if (0 != (Socket->SharedData->AsyncEvents & FD_READ) &&
4219 0 == (Socket->SharedData->AsyncDisabledEvents & FD_READ))
4220 {
4221 /* Make the Notification */
4223 Socket->SharedData->wMsg,
4224 Socket->Handle,
4226 /* Disable this event until the next read(); */
4228 }
4229 break;
4230
4232 if (0 != (Socket->SharedData->AsyncEvents & FD_OOB) &&
4233 0 == (Socket->SharedData->AsyncDisabledEvents & FD_OOB))
4234 {
4235 /* Make the Notification */
4237 Socket->SharedData->wMsg,
4238 Socket->Handle,
4240 /* Disable this event until the next read(); */
4242 }
4243 break;
4244
4245 case AFD_EVENT_SEND:
4246 if (0 != (Socket->SharedData->AsyncEvents & FD_WRITE) &&
4247 0 == (Socket->SharedData->AsyncDisabledEvents & FD_WRITE))
4248 {
4249 /* Make the Notification */
4251 Socket->SharedData->wMsg,
4252 Socket->Handle,
4254 /* Disable this event until the next write(); */
4256 }
4257 break;
4258
4259 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
4260 case AFD_EVENT_CONNECT:
4262 if (0 != (Socket->SharedData->AsyncEvents & FD_CONNECT) &&
4263 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CONNECT))
4264 {
4265 /* Make the Notification */
4267 Socket->SharedData->wMsg,
4268 Socket->Handle,
4270 /* Disable this event forever; */
4272 }
4273 break;
4274
4275 case AFD_EVENT_ACCEPT:
4276 if (0 != (Socket->SharedData->AsyncEvents & FD_ACCEPT) &&
4277 0 == (Socket->SharedData->AsyncDisabledEvents & FD_ACCEPT))
4278 {
4279 /* Make the Notification */
4281 Socket->SharedData->wMsg,
4282 Socket->Handle,
4284 /* Disable this event until the next accept(); */
4286 }
4287 break;
4288
4290 case AFD_EVENT_ABORT:
4291 case AFD_EVENT_CLOSE:
4292 if (0 != (Socket->SharedData->AsyncEvents & FD_CLOSE) &&
4293 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CLOSE))
4294 {
4295 /* Make the Notification */
4297 Socket->SharedData->wMsg,
4298 Socket->Handle,
4300 /* Disable this event forever; */
4302 }
4303 break;
4304 /* FIXME: Support QOS */
4305 }
4306 }
4307
4308 /* Check if there are any events left for us to check */
4309 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
4310 {
4311 return;
4312 }
4313
4314 /* Keep Polling */
4315 SockProcessAsyncSelect(Socket, AsyncData);
4316 return;
4317}
VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
Definition: dllmain.c:4319
WSPUPCALLTABLE Upcalls
Definition: dllmain.c:20
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define AFD_EVENT_ACCEPT
Definition: shared.h:226
#define AFD_EVENT_SEND
Definition: shared.h:221
#define AFD_EVENT_OOB_RECEIVE
Definition: shared.h:220
#define AFD_EVENT_CONNECT_FAIL
Definition: shared.h:227
#define AFD_EVENT_RECEIVE
Definition: shared.h:219
#define AFD_EVENT_DISCONNECT
Definition: shared.h:222
#define AFD_EVENT_ABORT
Definition: shared.h:223
#define AFD_EVENT_CLOSE
Definition: shared.h:224
#define AFD_EVENT_CONNECT
Definition: shared.h:225
ULONG Events
Definition: shared.h:51
AFD_HANDLE Handles[1]
Definition: shared.h:59
AFD_POLL_INFO AsyncSelectInfo
Definition: msafd.h:80
DWORD SequenceNumber
Definition: msafd.h:78
PSOCKET_INFORMATION ParentSocket
Definition: msafd.h:77
LONG AsyncDisabledEvents
Definition: shared.h:422
LONG AsyncEvents
Definition: shared.h:421
DWORD SequenceNumber
Definition: shared.h:419
LPWPUPOSTMESSAGE lpWPUPostMessage
Definition: ws2spi.h:609
#define FD_READ
Definition: winsock.h:399
#define FD_CLOSE
Definition: winsock.h:404
#define WSAMAKESELECTREPLY(e, error)
Definition: winsock.h:472
#define FD_OOB
Definition: winsock.h:401
#define FD_ACCEPT
Definition: winsock.h:402

Referenced by SockGetAsyncSelectHelperAfdHandle(), and SockProcessAsyncSelect().

◆ SockAsyncThread()

ULONG NTAPI SockAsyncThread ( PVOID  ThreadParam)

Definition at line 4094 of file dllmain.c.

4095{
4096 PVOID AsyncContext;
4097 PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine;
4098 IO_STATUS_BLOCK IOSB;
4100
4101 /* Make the Thread Higher Priority */
4103
4104 /* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */
4105 do
4106 {
4108 (PVOID*)&AsyncCompletionRoutine,
4109 &AsyncContext,
4110 &IOSB,
4111 NULL);
4112 /* Call the Async Function */
4113 if (NT_SUCCESS(Status))
4114 {
4115 (*AsyncCompletionRoutine)(AsyncContext, &IOSB);
4116 }
4117 else
4118 {
4119 /* It Failed, sleep for a second */
4120 Sleep(1000);
4121 }
4122 } while ((Status != STATUS_TIMEOUT));
4123
4124 /* The Thread has Ended */
4125 return 0;
4126}
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:758
HANDLE SockAsyncCompletionPort
Definition: dllmain.c:28
VOID(* PASYNC_COMPLETION_ROUTINE)(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: msafd.h:511
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
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1195
#define THREAD_PRIORITY_ABOVE_NORMAL
Definition: winbase.h:300

Referenced by SockCreateOrReferenceAsyncThread().

◆ SockCreateOrReferenceAsyncThread()

BOOLEAN SockCreateOrReferenceAsyncThread ( VOID  )

Definition at line 4033 of file dllmain.c.

4034{
4035 HANDLE hAsyncThread;
4036 DWORD AsyncThreadId;
4037 HANDLE AsyncEvent;
4040
4041 /* Check if the Thread Already Exists */
4043 {
4045 return TRUE;
4046 }
4047
4048 /* Create the Completion Port */
4050 {
4053 NULL,
4054 2); // Allow 2 threads only
4055 if (!NT_SUCCESS(Status))
4056 {
4057 ERR("Failed to create completion port: 0x%08x\n", Status);
4058 return FALSE;
4059 }
4060 /* Protect Handle */
4061 HandleFlags.ProtectFromClose = TRUE;
4062 HandleFlags.Inherit = FALSE;
4065 &HandleFlags,
4066 sizeof(HandleFlags));
4067 }
4068
4069 /* Create the Async Event */
4070 Status = NtCreateEvent(&AsyncEvent,
4072 NULL,
4074 FALSE);
4075
4076 /* Create the Async Thread */
4077 hAsyncThread = CreateThread(NULL,
4078 0,
4080 NULL,
4081 0,
4082 &AsyncThreadId);
4083
4084 /* Close the Handle */
4085 NtClose(hAsyncThread);
4086
4087 /* Increase the Reference Count */
4089 return TRUE;
4090}
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
ULONG NTAPI SockAsyncThread(PVOID ThreadParam)
Definition: dllmain.c:4094
ULONG SockAsyncThreadRefCount
Definition: dllmain.c:26
NTSTATUS NTAPI NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG NumberOfConcurrentThreads)
Definition: iocomp.c:253
#define ASSERT(a)
Definition: mode.c:44
#define IO_COMPLETION_ALL_ACCESS
Definition: file.c:43
@ ObjectHandleFlagInformation
Definition: obtypes.h:267
@ NotificationEvent
NTSTATUS NTAPI NtSetInformationObject(_In_ HANDLE ObjectHandle, _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, _In_reads_bytes_(Length) PVOID ObjectInformation, _In_ ULONG Length)
Sets information for an object or for a handle to an object.
Definition: oblife.c:1845

Referenced by SockReenableAsyncSelectEvent(), and WSPAsyncSelect().

◆ SockGetAsyncSelectHelperAfdHandle()

BOOLEAN SockGetAsyncSelectHelperAfdHandle ( VOID  )

Definition at line 4128 of file dllmain.c.

4129{
4130 UNICODE_STRING AfdHelper;
4132 IO_STATUS_BLOCK IoSb;
4133 FILE_COMPLETION_INFORMATION CompletionInfo;
4135
4136 /* First, make sure we're not already initialized */
4138 {
4139 return TRUE;
4140 }
4141
4142 /* Set up Handle Name and Object */
4143 RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" );
4145 &AfdHelper,
4147 NULL,
4148 NULL);
4149
4150 /* Open the Handle to AFD */
4154 &IoSb,
4155 NULL,
4156 0,
4159 0,
4160 NULL,
4161 0);
4162
4163 /*
4164 * Now Set up the Completion Port Information
4165 * This means that whenever a Poll is finished, the routine will be executed
4166 */
4167 CompletionInfo.Port = SockAsyncCompletionPort;
4168 CompletionInfo.Key = SockAsyncSelectCompletionRoutine;
4170 &IoSb,
4171 &CompletionInfo,
4172 sizeof(CompletionInfo),
4174
4175
4176 /* Protect the Handle */
4177 HandleFlags.ProtectFromClose = TRUE;
4178 HandleFlags.Inherit = FALSE;
4181 &HandleFlags,
4182 sizeof(HandleFlags));
4183
4184
4185 /* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */
4187 return TRUE;
4188}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define GENERIC_READ
Definition: compat.h:135
#define FILE_SHARE_READ
Definition: compat.h:136
VOID SockAsyncSelectCompletionRoutine(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:4190
HANDLE SockAsyncHelperAfdHandle
Definition: dllmain.c:27
BOOLEAN SockAsyncSelectCalled
Definition: dllmain.c:29
#define L(x)
Definition: resources.c:13
@ FileCompletionInformation
Definition: from_kernel.h:91
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
#define GENERIC_WRITE
Definition: nt_native.h:90
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225

Referenced by WSPAsyncSelect().

◆ SockProcessAsyncSelect()

VOID SockProcessAsyncSelect ( PSOCKET_INFORMATION  Socket,
PASYNC_DATA  AsyncData 
)

Definition at line 4319 of file dllmain.c.

4320{
4321
4322 ULONG lNetworkEvents;
4324
4325 /* Set up the Async Data Event Info */
4326 AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF;
4327 AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF;
4328 AsyncData->AsyncSelectInfo.HandleCount = 1;
4329 AsyncData->AsyncSelectInfo.Exclusive = TRUE;
4330 AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle;
4331 AsyncData->AsyncSelectInfo.Handles[0].Events = 0;
4332
4333 /* Remove unwanted events */
4334 lNetworkEvents = Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents);
4335
4336 /* Set Events to wait for */
4337 if (lNetworkEvents & FD_READ)
4338 {
4340 }
4341
4342 if (lNetworkEvents & FD_WRITE)
4343 {
4345 }
4346
4347 if (lNetworkEvents & FD_OOB)
4348 {
4350 }
4351
4352 if (lNetworkEvents & FD_ACCEPT)
4353 {
4355 }
4356
4357 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
4358 if (lNetworkEvents & FD_CONNECT)
4359 {
4361 }
4362
4363 if (lNetworkEvents & FD_CLOSE)
4364 {
4366 }
4367
4368 if (lNetworkEvents & FD_QOS)
4369 {
4371 }
4372
4373 if (lNetworkEvents & FD_GROUP_QOS)
4374 {
4376 }
4377
4378 /* Send IOCTL */
4380 NULL,
4381 NULL,
4382 AsyncData,
4383 &AsyncData->IoStatusBlock,
4385 &AsyncData->AsyncSelectInfo,
4386 sizeof(AsyncData->AsyncSelectInfo),
4387 &AsyncData->AsyncSelectInfo,
4388 sizeof(AsyncData->AsyncSelectInfo));
4389
4390 /* I/O Manager Won't call the completion routine, let's do it manually */
4391 if (NT_SUCCESS(Status))
4392 {
4393 return;
4394 }
4395 else
4396 {
4397 AsyncData->IoStatusBlock.Status = Status;
4398 SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock);
4399 }
4400}
#define IOCTL_AFD_SELECT
Definition: shared.h:303
#define AFD_EVENT_QOS
Definition: shared.h:228
#define AFD_EVENT_GROUP_QOS
Definition: shared.h:229
SOCKET Handle
Definition: shared.h:50
LARGE_INTEGER Timeout
Definition: shared.h:56
ULONG HandleCount
Definition: shared.h:57
ULONG_PTR Exclusive
Definition: shared.h:58
IO_STATUS_BLOCK IoStatusBlock
Definition: msafd.h:79
ULONG LowPart
Definition: typedefs.h:106
#define FD_QOS
Definition: winsock2.h:300
#define FD_GROUP_QOS
Definition: winsock2.h:302

Referenced by SockAsyncSelectCompletionRoutine(), and SockProcessQueuedAsyncSelect().

◆ SockProcessQueuedAsyncSelect()

VOID SockProcessQueuedAsyncSelect ( PVOID  Context,
PIO_STATUS_BLOCK  IoStatusBlock 
)

Definition at line 4402 of file dllmain.c.

4403{
4404 PASYNC_DATA AsyncData = Context;
4405 BOOL FreeContext = TRUE;
4406 PSOCKET_INFORMATION Socket;
4407
4408 /* Get the Socket */
4409 Socket = AsyncData->ParentSocket;
4410
4411 /* If someone closed it, stop the function */
4412 if (Socket->SharedData->State != SocketClosed)
4413 {
4414 /* Check if the Sequence Number changed by now, in which case quit */
4415 if (AsyncData->SequenceNumber == Socket->SharedData->SequenceNumber)
4416 {
4417 /* Do the actual select, if needed */
4418 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)))
4419 {
4420 SockProcessAsyncSelect(Socket, AsyncData);
4421 FreeContext = FALSE;
4422 }
4423 }
4424 }
4425
4426 /* Free the Context */
4427 if (FreeContext)
4428 {
4429 HeapFree(GetProcessHeap(), 0, AsyncData);
4430 }
4431
4432 return;
4433}
unsigned int BOOL
Definition: ntddk_ex.h:94
@ SocketClosed
Definition: shared.h:379

Referenced by SockReenableAsyncSelectEvent(), and WSPAsyncSelect().

◆ SockReenableAsyncSelectEvent()

VOID SockReenableAsyncSelectEvent ( IN PSOCKET_INFORMATION  Socket,
IN ULONG  Event 
)

Definition at line 4436 of file dllmain.c.

4438{
4439 PASYNC_DATA AsyncData;
4440
4441 /* Make sure the event is actually disabled */
4442 if (!(Socket->SharedData->AsyncDisabledEvents & Event))
4443 {
4444 return;
4445 }
4446
4447 /* Re-enable it */
4448 Socket->SharedData->AsyncDisabledEvents &= ~Event;
4449
4450 /* Return if no more events are being polled */
4451 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
4452 {
4453 return;
4454 }
4455
4456 /* Wait on new events */
4457 AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(ASYNC_DATA));
4458 if (!AsyncData) return;
4459
4460 /* Create the Asynch Thread if Needed */
4462
4463 /* Increase the sequence number to stop anything else */
4464 Socket->SharedData->SequenceNumber++;
4465
4466 /* Set up the Async Data */
4467 AsyncData->ParentSocket = Socket;
4468 AsyncData->SequenceNumber = Socket->SharedData->SequenceNumber;
4469
4470 /* Begin Async Select by using I/O Completion */
4473 AsyncData,
4474 0,
4475 0);
4476
4477 /* All done */
4478 return;
4479}
BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
Definition: dllmain.c:4033
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:4402
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
Definition: iocomp.c:569

Referenced by MsafdConnectAPC(), MsafdRecvAPC(), MsafdSendAPC(), MsafdUpdateConnectionContext(), WSPAccept(), WSPConnect(), WSPGetOverlappedResult(), WSPRecv(), WSPRecvFrom(), WSPSend(), and WSPSendTo().

◆ TranslateNtStatusError()

INT TranslateNtStatusError ( NTSTATUS  Status)

Definition at line 537 of file dllmain.c.

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}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define STATUS_ACCESS_VIOLATION
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:651
#define STATUS_NETWORK_UNREACHABLE
Definition: ntstatus.h:826
#define STATUS_CANT_WAIT
Definition: ntstatus.h:546
#define STATUS_ADDRESS_ALREADY_EXISTS
Definition: ntstatus.h:776
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:626
#define STATUS_HOST_UNREACHABLE
Definition: ntstatus.h:827
#define STATUS_REMOTE_DISCONNECT
Definition: ntstatus.h:646
#define STATUS_INVALID_CONNECTION
Definition: ntstatus.h:650
#define STATUS_REMOTE_NOT_LISTENING
Definition: ntstatus.h:518
#define STATUS_LOCAL_DISCONNECT
Definition: ntstatus.h:645
#define STATUS_PROTOCOL_NOT_SUPPORTED
Definition: ntstatus.h:1410
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define WSAEADDRNOTAVAIL
Definition: winerror.h:2865
#define WSAEOPNOTSUPP
Definition: winerror.h:2861
#define WSAEHOSTUNREACH
Definition: winerror.h:2881
#define WSAEWOULDBLOCK
Definition: winerror.h:2851
#define WSAEINVAL
Definition: winerror.h:2845
#define WSAECONNABORTED
Definition: winerror.h:2869
#define WSAENETDOWN
Definition: winerror.h:2866
#define WSAENOBUFS
Definition: winerror.h:2871
#define WSAETIMEDOUT
Definition: winerror.h:2876
#define WSAEMSGSIZE
Definition: winerror.h:2856
#define WSAECONNRESET
Definition: winerror.h:2870
#define WSAEACCES
Definition: winerror.h:2843
#define WSAESHUTDOWN
Definition: winerror.h:2874
#define WSAENETUNREACH
Definition: winerror.h:2867
#define WSAEAFNOSUPPORT
Definition: winerror.h:2863
#define WSAECONNREFUSED
Definition: winerror.h:2877
#define WSAENOTCONN
Definition: winerror.h:2873
#define WSAEADDRINUSE
Definition: winerror.h:2864
#define WSAEFAULT
Definition: winerror.h:2844
#define WSA_OPERATION_ABORTED
Definition: winsock2.h:615
#define WSA_IO_PENDING
Definition: winsock2.h:610

Referenced by MsafdConnectAPC(), MsafdReturnWithErrno(), MsafdUpdateConnectionContext(), WSPAccept(), WSPAcceptEx(), WSPBind(), WSPConnect(), WSPConnectEx(), WSPEnumNetworkEvents(), WSPGetOverlappedResult(), WSPListen(), WSPShutdown(), and WSPSocket().

◆ WSPAccept()

_Must_inspect_result_ SOCKET WSPAPI WSPAccept ( _In_ SOCKET  Handle,
_Out_writes_bytes_to_opt_ *, *addrlen struct sockaddr FAR *  SocketAddress,
_Inout_opt_ LPINT  SocketAddressLength,
_In_opt_ LPCONDITIONPROC  lpfnCondition,
_In_opt_ DWORD_PTR  dwCallbackData,
_Out_ LPINT  lpErrno 
)

Definition at line 1451 of file dllmain.c.

1458{
1459 IO_STATUS_BLOCK IOSB;
1460 PAFD_RECEIVED_ACCEPT_DATA ListenReceiveData;
1461 AFD_ACCEPT_DATA AcceptData;
1462 AFD_DEFER_ACCEPT_DATA DeferData;
1463 AFD_PENDING_ACCEPT_DATA PendingAcceptData;
1464 PSOCKET_INFORMATION Socket = NULL;
1466 struct fd_set ReadSet;
1467 struct timeval Timeout;
1468 PVOID PendingData = NULL;
1469 ULONG PendingDataLength = 0;
1470 PVOID CalleeDataBuffer;
1471 WSABUF CallerData, CalleeID, CallerID, CalleeData;
1473 GROUP GroupID = 0;
1474 ULONG CallBack;
1476 PSOCKET_INFORMATION AcceptSocketInfo;
1477 UCHAR ReceiveBuffer[0x1A];
1479
1480 /* Get the Socket Structure associate to this Socket*/
1481 Socket = GetSocketStructure(Handle);
1482 if (!Socket)
1483 {
1484 if (lpErrno) *lpErrno = WSAENOTSOCK;
1485 return SOCKET_ERROR;
1486 }
1487 if (!Socket->SharedData->Listening)
1488 {
1489 if (lpErrno) *lpErrno = WSAEINVAL;
1490 return SOCKET_ERROR;
1491 }
1492 if ((SocketAddress && !SocketAddressLength) ||
1493 (SocketAddressLength && !SocketAddress) ||
1494 (SocketAddressLength && *SocketAddressLength < sizeof(SOCKADDR)))
1495 {
1496 if (lpErrno) *lpErrno = WSAEFAULT;
1497 return INVALID_SOCKET;
1498 }
1499
1502 NULL,
1504 FALSE);
1505
1506 if( !NT_SUCCESS(Status) )
1507 {
1508 return SOCKET_ERROR;
1509 }
1510
1511 /* Dynamic Structure...ugh */
1512 ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
1513
1514 /* If this is non-blocking, make sure there's something for us to accept */
1515 if (Socket->SharedData->NonBlocking)
1516 {
1517 FD_ZERO(&ReadSet);
1518 FD_SET(Socket->Handle, &ReadSet);
1519 Timeout.tv_sec=0;
1520 Timeout.tv_usec=0;
1521
1522 if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
1523 {
1525 return SOCKET_ERROR;
1526 }
1527
1528 if (ReadSet.fd_array[0] != Socket->Handle)
1529 {
1531 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
1532 return SOCKET_ERROR;
1533 }
1534 }
1535
1536 /* Send IOCTL */
1538 SockEvent,
1539 NULL,
1540 NULL,
1541 &IOSB,
1543 NULL,
1544 0,
1545 ListenReceiveData,
1546 0xA + sizeof(*ListenReceiveData));
1547
1548 /* Wait for return */
1549 if (Status == STATUS_PENDING)
1550 {
1552 Status = IOSB.Status;
1553 }
1554
1555 if (!NT_SUCCESS(Status))
1556 {
1557 NtClose( SockEvent );
1558 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1559 }
1560
1561 if (lpfnCondition != NULL)
1562 {
1563 if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECT_DATA) != 0)
1564 {
1565 /* Find out how much data is pending */
1566 PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1567 PendingAcceptData.ReturnSize = TRUE;
1568
1569 /* Send IOCTL */
1571 SockEvent,
1572 NULL,
1573 NULL,
1574 &IOSB,
1576 &PendingAcceptData,
1577 sizeof(PendingAcceptData),
1578 &PendingAcceptData,
1579 sizeof(PendingAcceptData));
1580
1581 /* Wait for return */
1582 if (Status == STATUS_PENDING)
1583 {
1585 Status = IOSB.Status;
1586 }
1587
1588 if (!NT_SUCCESS(Status))
1589 {
1590 NtClose( SockEvent );
1591 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1592 }
1593
1594 /* How much data to allocate */
1595 PendingDataLength = IOSB.Information;
1596
1597 if (PendingDataLength)
1598 {
1599 /* Allocate needed space */
1600 PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
1601 if (!PendingData)
1602 {
1604 }
1605
1606 /* We want the data now */
1607 PendingAcceptData.ReturnSize = FALSE;
1608
1609 /* Send IOCTL */
1611 SockEvent,
1612 NULL,
1613 NULL,
1614 &IOSB,
1616 &PendingAcceptData,
1617 sizeof(PendingAcceptData),
1618 PendingData,
1619 PendingDataLength);
1620
1621 /* Wait for return */
1622 if (Status == STATUS_PENDING)
1623 {
1625 Status = IOSB.Status;
1626 }
1627
1628 if (!NT_SUCCESS(Status))
1629 {
1630 NtClose( SockEvent );
1631 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1632 }
1633 }
1634 }
1635
1636 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1637 {
1638 /* I don't support this yet */
1639 }
1640
1641 /* Build Callee ID */
1642 CalleeID.buf = (PVOID)Socket->LocalAddress;
1643 CalleeID.len = Socket->SharedData->SizeOfLocalAddress;
1644
1646 if (!RemoteAddress)
1647 {
1649 }
1650
1651 /* Set up Address in SOCKADDR Format */
1653 &ListenReceiveData->Address.Address[0].AddressType,
1654 sizeof(*RemoteAddress));
1655
1656 /* Build Caller ID */
1657 CallerID.buf = (PVOID)RemoteAddress;
1658 CallerID.len = sizeof(*RemoteAddress);
1659
1660 /* Build Caller Data */
1661 CallerData.buf = PendingData;
1662 CallerData.len = PendingDataLength;
1663
1664 /* Check if socket supports Conditional Accept */
1665 if (Socket->SharedData->UseDelayedAcceptance != 0)
1666 {
1667 /* Allocate Buffer for Callee Data */
1668 CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
1669 if (!CalleeDataBuffer) {
1671 }
1672 CalleeData.buf = CalleeDataBuffer;
1673 CalleeData.len = 4096;
1674 }
1675 else
1676 {
1677 /* Nothing */
1678 CalleeData.buf = 0;
1679 CalleeData.len = 0;
1680 }
1681
1682 /* Call the Condition Function */
1683 CallBack = (lpfnCondition)(&CallerID,
1684 CallerData.buf == NULL ? NULL : &CallerData,
1685 NULL,
1686 NULL,
1687 &CalleeID,
1688 CalleeData.buf == NULL ? NULL : &CalleeData,
1689 &GroupID,
1690 dwCallbackData);
1691
1692 if (((CallBack == CF_ACCEPT) && GroupID) != 0)
1693 {
1694 /* TBD: Check for Validity */
1695 }
1696
1697 if (CallBack == CF_ACCEPT)
1698 {
1699 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1700 {
1701 /* I don't support this yet */
1702 }
1703 if (CalleeData.buf)
1704 {
1705 // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0
1706 }
1707 }
1708 else
1709 {
1710 /* Callback rejected. Build Defer Structure */
1711 DeferData.SequenceNumber = ListenReceiveData->SequenceNumber;
1712 DeferData.RejectConnection = (CallBack == CF_REJECT);
1713
1714 /* Send IOCTL */
1716 SockEvent,
1717 NULL,
1718 NULL,
1719 &IOSB,
1721 &DeferData,
1722 sizeof(DeferData),
1723 NULL,
1724 0);
1725
1726 /* Wait for return */
1727 if (Status == STATUS_PENDING)
1728 {
1730 Status = IOSB.Status;
1731 }
1732
1733 NtClose( SockEvent );
1734
1735 if (!NT_SUCCESS(Status))
1736 {
1737 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1738 }
1739
1740 if (CallBack == CF_REJECT )
1741 {
1742 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1743 return SOCKET_ERROR;
1744 }
1745 else
1746 {
1747 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1748 return SOCKET_ERROR;
1749 }
1750 }
1751 }
1752
1753 /* Create a new Socket */
1755 Socket->SharedData->SocketType,
1756 Socket->SharedData->Protocol,
1757 &Socket->ProtocolInfo,
1758 GroupID,
1759 Socket->SharedData->CreateFlags,
1760 lpErrno);
1762 return SOCKET_ERROR;
1763
1764 /* Set up the Accept Structure */
1765 AcceptData.ListenHandle = (HANDLE)AcceptSocket;
1766 AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1767
1768 /* Send IOCTL to Accept */
1770 SockEvent,
1771 NULL,
1772 NULL,
1773 &IOSB,
1775 &AcceptData,
1776 sizeof(AcceptData),
1777 NULL,
1778 0);
1779
1780 /* Wait for return */
1781 if (Status == STATUS_PENDING)
1782 {
1784 Status = IOSB.Status;
1785 }
1786
1788 if (!NT_SUCCESS(Status))
1789 {
1791 WSPCloseSocket( AcceptSocket, lpErrno );
1792 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1793 }
1794
1795 AcceptSocketInfo = GetSocketStructure(AcceptSocket);
1796 if (!AcceptSocketInfo)
1797 {
1799 WSPCloseSocket( AcceptSocket, lpErrno );
1801 }
1802
1803 AcceptSocketInfo->SharedData->State = SocketConnected;
1804 AcceptSocketInfo->SharedData->ConnectTime = GetCurrentTimeInSeconds();
1805 AcceptSocketInfo->SharedData->NonBlocking = Socket->SharedData->NonBlocking;
1806
1807 /* Return Address in SOCKADDR FORMAT */
1808 if( SocketAddress )
1809 {
1810 RtlCopyMemory (SocketAddress,
1811 &ListenReceiveData->Address.Address[0].AddressType,
1812 sizeof(*RemoteAddress));
1813 if( SocketAddressLength )
1814 *SocketAddressLength = sizeof(*RemoteAddress);
1815 }
1816
1817 NtClose( SockEvent );
1818
1819 /* Re-enable Async Event */
1821
1822 TRACE("Socket %x\n", AcceptSocket);
1823
1825 {
1826 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1827 Socket->Handle,
1828 Socket->TdiAddressHandle,
1829 Socket->TdiConnectionHandle,
1831
1832 if (Status)
1833 {
1834 if (lpErrno) *lpErrno = Status;
1835 return SOCKET_ERROR;
1836 }
1837 }
1838
1839 if (lpErrno) *lpErrno = NO_ERROR;
1840
1841 /* Return Socket */
1842 return AcceptSocket;
1843}
int WSPAPI WSPSelect(IN int nfds, IN OUT fd_set *readfds OPTIONAL, IN OUT fd_set *writefds OPTIONAL, IN OUT fd_set *exceptfds OPTIONAL, IN const struct timeval *timeout OPTIONAL, OUT LPINT lpErrno)
Definition: dllmain.c:1082
INT WSPAPI WSPCloseSocket(IN SOCKET Handle, OUT LPINT lpErrno)
Definition: dllmain.c:637
SOCKET WSPAPI WSPSocket(int AddressFamily, int SocketType, int Protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)
Definition: dllmain.c:48
static ULONG Timeout
Definition: ping.c:61
#define IOCTL_AFD_WAIT_FOR_LISTEN
Definition: shared.h:291
#define IOCTL_AFD_DEFER_ACCEPT
Definition: shared.h:351
struct _AFD_RECEIVED_ACCEPT_DATA * PAFD_RECEIVED_ACCEPT_DATA
#define IOCTL_AFD_ACCEPT
Definition: shared.h:293
#define IOCTL_AFD_GET_PENDING_CONNECT_DATA
Definition: shared.h:353
HANDLE ListenHandle
Definition: shared.h:65
ULONG SequenceNumber
Definition: shared.h:64
BOOLEAN RejectConnection
Definition: shared.h:91
TRANSPORT_ADDRESS Address
Definition: shared.h:80
WSAPROTOCOL_INFOW ProtocolInfo
Definition: msafd.h:62
BOOLEAN NonBlocking
Definition: shared.h:403
BOOLEAN Listening
Definition: shared.h:397
BOOLEAN UseDelayedAcceptance
Definition: shared.h:407
DWORD ServiceFlags1
Definition: shared.h:411
USHORT AddressType
Definition: tdi.h:339
TA_ADDRESS Address[1]
Definition: tdi.h:377
ULONG len
Definition: ws2def.h:525
CHAR FAR * buf
Definition: ws2def.h:526
Definition: winsock.h:60
unsigned char UCHAR
Definition: typedefs.h:53
void * PVOID
Definition: typedefs.h:50
unsigned int GROUP
Definition: winsock2.h:634
#define CF_REJECT
Definition: winsock2.h:408
#define XP1_QOS_SUPPORTED
Definition: winsock2.h:443
#define CF_ACCEPT
Definition: winsock2.h:407
#define XP1_CONNECT_DATA
Definition: winsock2.h:437
#define FD_ZERO(set)
Definition: winsock.h:90
#define INVALID_SOCKET
Definition: winsock.h:326
UINT_PTR SOCKET
Definition: winsock.h:41
#define FD_SET(fd, set)
Definition: winsock.h:83
#define WSH_NOTIFY_ACCEPT
Definition: wsahelp.h:13
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _In_opt_ PWSK_SOCKET AcceptSocket
Definition: wsk.h:173
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR RemoteAddress
Definition: wsk.h:172

Referenced by WSPStartup().

◆ WSPAcceptEx()

BOOL WSPAPI WSPAcceptEx ( _In_ SOCKET  sListenSocket,
_In_ SOCKET  sAcceptSocket,
_Out_ PVOID  lpOutputBuffer,
_In_ DWORD  dwReceiveDataLength,
_In_ DWORD  dwLocalAddressLength,
_In_ DWORD  dwRemoteAddressLength,
_Out_ LPDWORD  lpdwBytesReceived,
_Inout_ LPOVERLAPPED  lpOverlapped 
)

Definition at line 1847 of file dllmain.c.

1856{
1857 PSOCKET_INFORMATION ListenSocket = GetSocketStructure(sListenSocket);
1859 AFD_SUPER_ACCEPT_INFO AcceptInfo;
1862
1863 /* Validate sockets */
1864 if (!ListenSocket || !AcceptSocket)
1865 {
1867 return FALSE;
1868 }
1869
1870 if (!lpOverlapped)
1871 {
1873 return FALSE;
1874 }
1875
1876 /* Check if this socket is listening and that AcceptEx hasn't already been invoked */
1877 if (!ListenSocket->SharedData->Listening)
1878 {
1880 return FALSE;
1881 }
1882
1883 /* Make sure that the accept socket is not already opened or connected */
1884 if (AcceptSocket->SharedData->State != SocketOpen)
1885 {
1887 return FALSE;
1888 }
1889
1890 if (!lpOutputBuffer || !dwRemoteAddressLength)
1891 {
1893 return FALSE;
1894 }
1895
1896 /* Populate IOCTL super accept structure */
1897 AcceptInfo.SanActive = FALSE;
1898 AcceptInfo.FixAddressAlignment = TRUE;
1899 AcceptInfo.AcceptHandle = (HANDLE)AcceptSocket->Handle;
1903
1904 IoStatusBlock->Information = 0;
1905 IoStatusBlock->Status = STATUS_PENDING;
1906
1907 Status = NtDeviceIoControlFile((HANDLE)ListenSocket->Handle,
1908 lpOverlapped->hEvent,
1909 NULL,
1910 lpOverlapped->hEvent ? NULL : lpOverlapped,
1913 &AcceptInfo,
1914 sizeof(AcceptInfo),
1915 lpOutputBuffer,
1917
1918 if (Status == STATUS_PENDING)
1919 {
1921 return FALSE;
1922 }
1923
1925 *lpdwBytesReceived = IoStatusBlock->Information;
1926
1928
1929 return NT_SUCCESS(Status);
1930}
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
_In_ SOCKET sAcceptSocket
Definition: mswsock.h:100
_In_ SOCKET _In_ DWORD _In_ DWORD _In_ DWORD _Out_ LPDWORD lpdwBytesReceived
Definition: mswsock.h:105
_In_ SOCKET _In_ DWORD dwReceiveDataLength
Definition: mswsock.h:102
_In_ SOCKET _In_ DWORD _In_ DWORD _In_ DWORD dwRemoteAddressLength
Definition: mswsock.h:104
_In_ SOCKET _In_ DWORD _In_ DWORD dwLocalAddressLength
Definition: mswsock.h:103
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:93
#define IOCTL_AFD_SUPER_ACCEPT
Definition: shared.h:347
@ SocketOpen
Definition: shared.h:375
ULONG ReceiveDataLength
Definition: shared.h:73
BOOLEAN FixAddressAlignment
Definition: shared.h:71
ULONG RemoteAddressLength
Definition: shared.h:75
ULONG LocalAddressLength
Definition: shared.h:74

Referenced by WSPIoctl().

◆ WSPAddressToString()

INT WSPAPI WSPAddressToString ( IN LPSOCKADDR  lpsaAddress,
IN DWORD  dwAddressLength,
IN LPWSAPROTOCOL_INFOW  lpProtocolInfo,
OUT LPWSTR  lpszAddressString,
IN OUT LPDWORD  lpdwAddressStringLength,
OUT LPINT  lpErrno 
)

Definition at line 3496 of file dllmain.c.

3502{
3503 SIZE_T size;
3504 WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
3505 WCHAR *p;
3506
3507 if (!lpsaAddress || !lpszAddressString || !lpdwAddressStringLength)
3508 {
3509 if (lpErrno) *lpErrno = WSAEFAULT;
3510 return SOCKET_ERROR;
3511 }
3512
3513 switch (lpsaAddress->sa_family)
3514 {
3515 case AF_INET:
3516 if (dwAddressLength < sizeof(SOCKADDR_IN))
3517 {
3518 if (lpErrno) *lpErrno = WSAEINVAL;
3519 return SOCKET_ERROR;
3520 }
3522 L"%u.%u.%u.%u:%u",
3523 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 24 & 0xff),
3524 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 16 & 0xff),
3525 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 8 & 0xff),
3526 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) & 0xff),
3527 ntohs(((SOCKADDR_IN *)lpsaAddress)->sin_port));
3528
3529 p = wcschr(buffer, L':');
3530 if (!((SOCKADDR_IN *)lpsaAddress)->sin_port)
3531 {
3532 *p = 0;
3533 }
3534 break;
3535 default:
3536 if (lpErrno) *lpErrno = WSAEINVAL;
3537 return SOCKET_ERROR;
3538 }
3539
3540 size = wcslen(buffer) + 1;
3541
3542 if (*lpdwAddressStringLength < size)
3543 {
3544 *lpdwAddressStringLength = size;
3545 if (lpErrno) *lpErrno = WSAEFAULT;
3546 return SOCKET_ERROR;
3547 }
3548
3549 *lpdwAddressStringLength = size;
3550 wcscpy(lpszAddressString, buffer);
3551 return 0;
3552}
#define wcschr
Definition: compat.h:17
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
#define AF_INET
Definition: tcpip.h:117
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLfloat GLfloat p
Definition: glext.h:8902
#define ntohl(x)
Definition: module.h:205
#define ntohs(x)
Definition: module.h:210
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
short WCHAR
Definition: pedump.c:58
wcscpy
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by WSPStartup().

◆ WSPBind()

INT WSPAPI WSPBind ( SOCKET  Handle,
const struct sockaddr *  SocketAddress,
int  SocketAddressLength,
LPINT  lpErrno 
)

Definition at line 860 of file dllmain.c.

864{
865 IO_STATUS_BLOCK IOSB;
866 PAFD_BIND_DATA BindData;
867 PSOCKET_INFORMATION Socket = NULL;
869 SOCKADDR_INFO SocketInfo;
871 ULONG connectSize;
872
873 /* Get the Socket Structure associate to this Socket*/
874 Socket = GetSocketStructure(Handle);
875 if (!Socket)
876 {
877 if (lpErrno) *lpErrno = WSAENOTSOCK;
878 return SOCKET_ERROR;
879 }
880 if (Socket->SharedData->State != SocketOpen)
881 {
882 if (lpErrno) *lpErrno = WSAEINVAL;
883 return SOCKET_ERROR;
884 }
885 if (!SocketAddress || SocketAddressLength < Socket->SharedData->SizeOfLocalAddress)
886 {
887 if (lpErrno) *lpErrno = WSAEINVAL;
888 return SOCKET_ERROR;
889 }
890
891 /* Get Address Information */
892 Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
893 SocketAddressLength,
894 &SocketInfo);
895
896 if (SocketInfo.AddressInfo == SockaddrAddressInfoBroadcast && !Socket->SharedData->Broadcast)
897 {
898 if (lpErrno) *lpErrno = WSAEADDRNOTAVAIL;
899 return SOCKET_ERROR;
900 }
901
904 NULL,
906 FALSE);
907
908 if (!NT_SUCCESS(Status))
909 {
910 return SOCKET_ERROR;
911 }
912
913 connectSize = FIELD_OFFSET(AFD_BIND_DATA, Address.Address[SocketAddressLength]);
914
915 /* See below */
916 BindData = HeapAlloc(GlobalHeap, 0, connectSize);
917 if (!BindData)
918 {
920 }
921
922 /* Set up Address in TDI Format */
923 BindData->Address.TAAddressCount = 1;
924 BindData->Address.Address[0].AddressLength = (USHORT)(SocketAddressLength - sizeof(SocketAddress->sa_family));
925 BindData->Address.Address[0].AddressType = SocketAddress->sa_family;
926 RtlCopyMemory (BindData->Address.Address[0].Address,
927 SocketAddress->sa_data,
928 SocketAddressLength - sizeof(SocketAddress->sa_family));
929
930 /* Set the Share Type */
931 if (Socket->SharedData->ExclusiveAddressUse)
932 {
933 BindData->ShareType = AFD_SHARE_EXCLUSIVE;
934 }
935 else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard)
936 {
937 BindData->ShareType = AFD_SHARE_WILDCARD;
938 }
939 else if (Socket->SharedData->ReuseAddresses)
940 {
941 BindData->ShareType = AFD_SHARE_REUSE;
942 }
943 else
944 {
945 BindData->ShareType = AFD_SHARE_UNIQUE;
946 }
947
948 /* Send IOCTL */
950 SockEvent,
951 NULL,
952 NULL,
953 &IOSB,
955 BindData,
956 connectSize,
957 BindData,
958 connectSize);
959
960 /* Wait for return */
961 if (Status == STATUS_PENDING)
962 {
964 Status = IOSB.Status;
965 }
966
968 HeapFree(GlobalHeap, 0, BindData);
969
971 if (Status != STATUS_SUCCESS)
972 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
973
974 /* Set up Socket Data */
975 Socket->SharedData->State = SocketBound;
976 Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
977
979 {
980 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
981 Socket->Handle,
982 Socket->TdiAddressHandle,
983 Socket->TdiConnectionHandle,
985
986 if (Status)
987 {
988 if (lpErrno) *lpErrno = Status;
989 return SOCKET_ERROR;
990 }
991 }
992
993 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
994}
if(dx< 0)
Definition: linetemp.h:194
#define AFD_SHARE_WILDCARD
Definition: netio.c:69
#define AFD_SHARE_UNIQUE
Definition: netio.c:67
#define AFD_SHARE_EXCLUSIVE
Definition: netio.c:70
#define AFD_SHARE_REUSE
Definition: netio.c:68
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
#define IOCTL_AFD_BIND
Definition: shared.h:285
@ SocketBound
Definition: shared.h:376
ULONG ShareType
Definition: shared.h:39
TRANSPORT_ADDRESS Address
Definition: shared.h:40
PWSH_GET_SOCKADDR_TYPE WSHGetSockaddrType
Definition: helpers.h:28
SOCKADDR_ADDRESS_INFO AddressInfo
Definition: wsahelp.h:44
SOCKADDR_ENDPOINT_INFO EndpointInfo
Definition: wsahelp.h:45
BOOLEAN Broadcast
Definition: shared.h:398
BOOLEAN ExclusiveAddressUse
Definition: shared.h:402
BOOLEAN ReuseAddresses
Definition: shared.h:401
UCHAR Address[1]
Definition: tdi.h:340
USHORT AddressLength
Definition: tdi.h:338
LONG TAAddressCount
Definition: tdi.h:376
u_short sa_family
Definition: winsock.h:211
char sa_data[14]
Definition: winsock.h:212
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
@ SockaddrEndpointInfoWildcard
Definition: wsahelp.h:31
@ SockaddrAddressInfoBroadcast
Definition: wsahelp.h:26
#define WSH_NOTIFY_BIND
Definition: wsahelp.h:10

Referenced by WSPConnect(), WSPRecvFrom(), WSPSendTo(), and WSPStartup().

◆ WSPCleanup()

INT WSPAPI WSPCleanup ( OUT LPINT  lpErrno)

Definition at line 3680 of file dllmain.c.

3682{
3683 TRACE("Leaving.\n");
3684
3685 if (lpErrno) *lpErrno = NO_ERROR;
3686
3687 return 0;
3688}

Referenced by WSPStartup(), and WsTpWSPCleanup().

◆ WSPCloseSocket()

INT WSPAPI WSPCloseSocket ( IN SOCKET  Handle,
OUT LPINT  lpErrno 
)

Definition at line 637 of file dllmain.c.

639{
641 PSOCKET_INFORMATION Socket = NULL, CurrentSocket;
644 AFD_DISCONNECT_INFO DisconnectInfo;
645 SOCKET_STATE OldState;
646 LONG LingerWait = -1;
647 DWORD References;
648
649 /* Get the Socket Structure associate to this Socket*/
650 Socket = GetSocketStructure(Handle);
651 if (!Socket)
652 {
653 if (lpErrno) *lpErrno = WSAENOTSOCK;
654 return SOCKET_ERROR;
655 }
656
657 /* HACK: Allow APC to be processed */
658 SleepEx(0, TRUE);
659
660 if (Socket->HelperEvents & WSH_NOTIFY_CLOSE)
661 {
662 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
663 Socket->Handle,
664 Socket->TdiAddressHandle,
665 Socket->TdiConnectionHandle,
667
668 if (Status)
669 {
670 ERR("WSHNotify failed. Error 0x%#x\n", Status);
671 if (lpErrno) *lpErrno = Status;
672 return SOCKET_ERROR;
673 }
674 }
675
676 /* If a Close is already in Process, give up */
677 if (Socket->SharedData->State == SocketClosed)
678 {
679 WARN("Socket is closing.\n");
680 if (lpErrno) *lpErrno = WSAENOTSOCK;
681 return SOCKET_ERROR;
682 }
683
684 /* Create the Wait Event */
687 NULL,
689 FALSE);
690 if (!NT_SUCCESS(Status))
691 {
692 ERR("NtCreateEvent failed: 0x%08x\n", Status);
693 return SOCKET_ERROR;
694 }
695
696 /* Decrement reference count on SharedData */
697 References = InterlockedDecrement(&Socket->SharedData->RefCount);
698 if (References)
699 goto ok;
700
701 /* Set the state to close */
702 OldState = Socket->SharedData->State;
703 Socket->SharedData->State = SocketClosed;
704
705 /* If SO_LINGER is ON and the Socket is connected, we need to disconnect */
706 /* FIXME: Should we do this on Datagram Sockets too? */
707 if ((OldState == SocketConnected) && (Socket->SharedData->LingerData.l_onoff))
708 {
709 ULONG SendsInProgress;
710 ULONG SleepWait;
711
712 /* We need to respect the timeout */
713 SleepWait = 100;
714 LingerWait = Socket->SharedData->LingerData.l_linger * 1000;
715
716 /* Loop until no more sends are pending, within the timeout */
717 while (LingerWait)
718 {
719 /* Find out how many Sends are in Progress */
720 if (GetSocketInformation(Socket,
722 NULL,
723 &SendsInProgress,
724 NULL,
725 NULL,
726 NULL))
727 {
728 /* Bail out if anything but NO_ERROR */
729 LingerWait = 0;
730 break;
731 }
732
733 /* Bail out if no more sends are pending */
734 if (!SendsInProgress)
735 {
736 LingerWait = -1;
737 break;
738 }
739
740 /*
741 * We have to execute a sleep, so it's kind of like
742 * a block. If the socket is Nonblock, we cannot
743 * go on since asynchronous operation is expected
744 * and we cannot offer it
745 */
746 if (Socket->SharedData->NonBlocking)
747 {
748 WARN("Would block!\n");
750 Socket->SharedData->State = OldState;
751 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
752 return SOCKET_ERROR;
753 }
754
755 /* Now we can sleep, and decrement the linger wait */
756 /*
757 * FIXME: It seems Windows does some funky acceleration
758 * since the waiting seems to be longer and longer. I
759 * don't think this improves performance so much, so we
760 * wait a fixed time instead.
761 */
762 Sleep(SleepWait);
763 LingerWait -= SleepWait;
764 }
765 }
766
767 if (OldState == SocketConnected)
768 {
769 if (LingerWait <= 0)
770 {
771 DisconnectInfo.Timeout.QuadPart = 0LL;
772 DisconnectInfo.DisconnectType = LingerWait < 0 ? AFD_DISCONNECT_SEND : AFD_DISCONNECT_ABORT;
773
774 if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData->SendShutdown)) ||
775 ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData->ReceiveShutdown)))
776 {
777 /* Send IOCTL */
779 SockEvent,
780 NULL,
781 NULL,
784 &DisconnectInfo,
785 sizeof(DisconnectInfo),
786 NULL,
787 0);
788
789 /* Wait for return */
790 if (Status == STATUS_PENDING)
791 {
793 Status = IoStatusBlock.Status;
794 }
795 }
796 }
797 }
798
799 /* Cleanup Time! */
800 Socket->HelperContext = NULL;
801 Socket->SharedData->AsyncDisabledEvents = -1;
802 NtClose(Socket->TdiAddressHandle);
803 Socket->TdiAddressHandle = NULL;
805 Socket->TdiConnectionHandle = NULL;
806ok:
808 if (SocketListHead == Socket)
809 {
811 }
812 else
813 {
814 CurrentSocket = SocketListHead;
815 while (CurrentSocket->NextSocket)
816 {
817 if (CurrentSocket->NextSocket == Socket)
818 {
819 CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket;
820 break;
821 }
822
823 CurrentSocket = CurrentSocket->NextSocket;
824 }
825 }
827
828 /* Close the handle */
831
833 {
834 /* It is a duplicated socket, so unmap the memory */
836 NtClose(Socket->SharedDataHandle);
837 Socket->SharedData = NULL;
838 }
839 if( !References && Socket->SharedData )
840 {
841 HeapFree(GlobalHeap, 0, Socket->SharedData);
842 }
843 HeapFree(GlobalHeap, 0, Socket);
844 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
845}
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define WARN(fmt,...)
Definition: precomp.h:61
#define UnmapViewOfFile
Definition: compat.h:746
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
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:3712
long LONG
Definition: pedump.c:60
#define AFD_DISCONNECT_ABORT
Definition: shared.h:215
#define IOCTL_AFD_DISCONNECT
Definition: shared.h:305
#define AFD_INFO_SENDS_IN_PROGRESS
Definition: shared.h:200
#define AFD_DISCONNECT_SEND
Definition: shared.h:213
LARGE_INTEGER Timeout
Definition: shared.h:153
ULONG DisconnectType
Definition: shared.h:152
HANDLE SharedDataHandle
Definition: msafd.h:48
BOOLEAN SendShutdown
Definition: shared.h:406
struct linger LingerData
Definition: shared.h:390
BOOLEAN ReceiveShutdown
Definition: shared.h:405
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:738
#define LL
Definition: tui.h:167
LONGLONG QuadPart
Definition: typedefs.h:114
#define WSH_NOTIFY_CLOSE
Definition: wsahelp.h:17
enum _SOCKET_STATE SOCKET_STATE

Referenced by WSPAccept(), and WSPStartup().

◆ WSPConnect()

int WSPAPI WSPConnect ( SOCKET  Handle,
const struct sockaddr *  SocketAddress,
int  SocketAddressLength,
LPWSABUF  lpCallerData,
LPWSABUF  lpCalleeData,
LPQOS  lpSQOS,
LPQOS  lpGQOS,
LPINT  lpErrno 
)

Definition at line 2017 of file dllmain.c.

2025{
2026 IO_STATUS_BLOCK DummyIOSB;
2027 PIO_STATUS_BLOCK IOSB = &DummyIOSB;
2028 PAFD_CONNECT_INFO ConnectInfo = NULL;
2029 PSOCKET_INFORMATION Socket;
2031 INT Errno;
2032 ULONG ConnectDataLength;
2033 ULONG InConnectDataLength;
2035 int SocketDataLength;
2036 PMSAFD_CONNECT_APC_CONTEXT APCContext = NULL;
2037 PIO_APC_ROUTINE APCFunction = NULL;
2038 UCHAR Buffer[128];
2039
2040 TRACE("WSPConnect(%x)\n", Handle);
2041
2042 /* Get the Socket Structure associate to this Socket*/
2043 Socket = GetSocketStructure(Handle);
2044 if (!Socket)
2045 {
2046 if (lpErrno) *lpErrno = WSAENOTSOCK;
2047 return SOCKET_ERROR;
2048 }
2049
2050 /* Bind us First */
2051 if (Socket->SharedData->State == SocketOpen)
2052 {
2053 INT BindAddressLength;
2054 PSOCKADDR BindAddress;
2055 INT BindError;
2056
2057 /* Get the Wildcard Address */
2058 BindAddressLength = Socket->HelperData->MaxWSAddressLength;
2059 BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength);
2060 if (!BindAddress)
2061 {
2063 }
2065 BindAddress,
2066 &BindAddressLength);
2067 /* Bind it */
2068 BindError = WSPBind(Handle, BindAddress, BindAddressLength, lpErrno);
2069 HeapFree(GetProcessHeap(), 0, BindAddress);
2070 if (BindError == SOCKET_ERROR)
2071 return SOCKET_ERROR;
2072 }
2073
2076 NULL,
2078 FALSE);
2079 if (!NT_SUCCESS(Status))
2080 return SOCKET_ERROR;
2081
2082 /* Set the Connect Data */
2083 if (lpCallerData != NULL)
2084 {
2085 ConnectDataLength = lpCallerData->len;
2087 SockEvent,
2088 NULL,
2089 NULL,
2090 IOSB,
2092 lpCallerData->buf,
2093 ConnectDataLength,
2094 NULL,
2095 0);
2096 /* Wait for return */
2097 if (Status == STATUS_PENDING)
2098 {
2100 Status = IOSB->Status;
2101 }
2102
2103 if (Status != STATUS_SUCCESS)
2104 goto Leave;
2105 }
2106
2107 /* Calculate the size of SocketAddress->sa_data */
2108 SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
2109
2110 ConnectInfo = (PAFD_CONNECT_INFO)Buffer;
2111
2112 int connectionInfoSize = FIELD_OFFSET(AFD_CONNECT_INFO, RemoteAddress.Address[0].Address[SocketDataLength]);
2113
2114 if (connectionInfoSize > 128)
2115 {
2116 *lpErrno = WSAEFAULT;
2117 return SOCKET_ERROR;
2118 }
2119
2120 /* Set up Address in TDI Format */
2121 ConnectInfo->RemoteAddress.TAAddressCount = 1;
2122 ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
2123 ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
2125 SocketAddress->sa_data,
2126 SocketDataLength);
2127
2128 /*
2129 * Disable FD_WRITE and FD_CONNECT
2130 * The latter fixes a race condition where the FD_CONNECT is re-enabled
2131 * at the end of this function right after the Async Thread disables it.
2132 * This should only happen at the *next* WSPConnect
2133 */
2134 if (Socket->SharedData->AsyncEvents & FD_CONNECT)
2135 {
2137 }
2138
2139 /* Tell AFD that we want Connection Data back, have it allocate a buffer */
2140 if (lpCalleeData != NULL)
2141 {
2142 InConnectDataLength = lpCalleeData->len;
2144 SockEvent,
2145 NULL,
2146 NULL,
2147 IOSB,
2149 &InConnectDataLength,
2150 sizeof(InConnectDataLength),
2151 NULL,
2152 0);
2153
2154 /* Wait for return */
2155 if (Status == STATUS_PENDING)
2156 {
2158 Status = IOSB->Status;
2159 }
2160
2161 if (Status != STATUS_SUCCESS)
2162 goto Leave;
2163 }
2164
2165 /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */
2166 ConnectInfo->Root = 0;
2167 ConnectInfo->UseSAN = FALSE;
2168 ConnectInfo->Unknown = 0;
2169
2170 /* Verify if we should use APC */
2171 if (Socket->SharedData->NonBlocking)
2172 {
2173 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(*APCContext));
2174 if (!APCContext)
2175 {
2176 ERR("Not enough memory for APC Context\n");
2178 goto Leave;
2179 }
2180 APCContext->lpSocket = Handle;
2181 APCFunction = &MsafdConnectAPC;
2182
2183 IOSB = &APCContext->IoStatusBlock;
2184 }
2185
2186 IOSB->Status = STATUS_PENDING;
2187 IOSB->Information = 0;
2188
2189 /* Send IOCTL */
2191 APCFunction ? NULL : SockEvent,
2192 APCFunction,
2193 APCContext,
2194 IOSB,
2196 ConnectInfo,
2197 connectionInfoSize,
2198 NULL,
2199 0);
2200 if (Socket->SharedData->NonBlocking)
2201 {
2202 if (Status == STATUS_PENDING)
2203 {
2204 Status = STATUS_CANT_WAIT; // WSAEWOULDBLOCK
2205 goto Leave;
2206 }
2207 else
2208 {
2209 /* HACK: Allow APC to be processed */
2210 SleepEx(0, TRUE);
2211 }
2212 }
2213 else
2214 {
2215 /* Wait for completion if blocking */
2216 if (Status == STATUS_PENDING)
2217 {
2219 Status = IOSB->Status;
2220 }
2221
2223 if (Status != STATUS_SUCCESS)
2224 goto Leave;
2225
2226 Socket->SharedData->State = SocketConnected;
2227 Socket->TdiConnectionHandle = (HANDLE)IOSB->Information;
2229 }
2230
2231 /* Get any pending connect data */
2232 if (lpCalleeData != NULL && Status == STATUS_SUCCESS)
2233 {
2234 IOSB = &DummyIOSB;
2236 SockEvent,
2237 NULL,
2238 NULL,
2239 IOSB,
2241 NULL,
2242 0,
2243 lpCalleeData->buf,
2244 lpCalleeData->len);
2245 /* Wait for return */
2246 if (Status == STATUS_PENDING)
2247 {
2249 Status = IOSB->Status;
2250 }
2251 }
2252
2253Leave:
2254 TRACE("Ending %lx\n", Status);
2255
2257
2258 /* Re-enable Async Event */
2260
2261 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
2263
2265 {
2266 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2267 Socket->Handle,
2268 Socket->TdiAddressHandle,
2269 Socket->TdiConnectionHandle,
2271
2272 if (Errno)
2273 {
2274 if (lpErrno) *lpErrno = Errno;
2275 return SOCKET_ERROR;
2276 }
2277 }
2279 {
2280 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2281 Socket->Handle,
2282 Socket->TdiAddressHandle,
2283 Socket->TdiConnectionHandle,
2285
2286 if (Errno)
2287 {
2288 if (lpErrno) *lpErrno = Errno;
2289 return SOCKET_ERROR;
2290 }
2291 }
2292
2293 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
2294}
Definition: bufpool.h:45
INT WSPAPI WSPBind(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPINT lpErrno)
Definition: dllmain.c:860
static VOID NTAPI MsafdConnectAPC(_In_ PVOID ApcContext, _In_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG Reserved)
Definition: dllmain.c:1964
struct _AFD_CONNECT_INFO * PAFD_CONNECT_INFO
#define IOCTL_AFD_SET_CONNECT_DATA
Definition: shared.h:321
#define IOCTL_AFD_CONNECT
Definition: shared.h:287
#define IOCTL_AFD_SET_CONNECT_DATA_SIZE
Definition: shared.h:337
#define IOCTL_AFD_GET_CONNECT_DATA
Definition: shared.h:329
TRANSPORT_ADDRESS RemoteAddress
Definition: shared.h:131
BOOLEAN UseSAN
Definition: shared.h:128
INT MaxWSAddressLength
Definition: helpers.h:17
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr
Definition: helpers.h:29
IO_STATUS_BLOCK IoStatusBlock
Definition: msafd.h:108
int32_t INT
Definition: typedefs.h:58

Referenced by WSPStartup().

◆ WSPConnectEx()

BOOL WSPAPI WSPConnectEx ( _In_ SOCKET  Handle,
_In_ const struct sockaddr *  SocketAddress,
_In_ int  SocketAddressLength,
_In_ PVOID  lpSendBuffer,
_In_ DWORD  dwSendDataLength,
_Out_ LPDWORD  lpdwBytesSent,
_Inout_ LPOVERLAPPED  lpOverlapped 
)

Definition at line 2298 of file dllmain.c.

2306{
2307 IO_STATUS_BLOCK DummyIOSB;
2308 PIO_STATUS_BLOCK IOSB = &DummyIOSB;
2309 PAFD_SUPER_CONNECT_INFO ConnectInfo = NULL;
2310 PSOCKET_INFORMATION Socket;
2312 int SocketDataLength;
2313 UCHAR Buffer[128];
2314
2315 if (!lpOverlapped)
2316 {
2318 return FALSE;
2319 }
2320
2321 if (!lpSendBuffer && dwSendDataLength)
2322 {
2324 return FALSE;
2325 }
2326
2327 /* Get the Socket Structure associate to this Socket*/
2328 Socket = GetSocketStructure(Handle);
2329 if (!Socket)
2330 {
2332 return FALSE;
2333 }
2334
2335
2336 /* Cannot call on connectionless socket */
2337 if (SocketAddressLength > ARRAYSIZE(Buffer) - sizeof(AFD_CONNECT_INFO) || Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS)
2338 {
2340 return SOCKET_ERROR;
2341 }
2342
2343 if (Socket->SharedData->State == SocketOpen)
2344 {
2345 /* Socket already must be bound */
2347 return FALSE;
2348 }
2349
2350 ConnectInfo = (PAFD_SUPER_CONNECT_INFO)Buffer;
2351 ConnectInfo->SanActive = FALSE;
2352
2353 /* Calculate the size of SocketAddress->sa_data */
2354 SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
2355
2356 /* Set up Address in TDI Format */
2357 ConnectInfo->RemoteAddress.TAAddressCount = 1;
2358 ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
2359 ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
2361 SocketAddress->sa_data,
2362 SocketDataLength);
2363
2364 /*
2365 * Disable FD_WRITE and FD_CONNECT.
2366 * The latter fixes a race condition where the FD_CONNECT is re-enabled
2367 * at the end of this function right after the Async Thread disables it.
2368 * This should only happen at the *next* WSPConnect.
2369 */
2370 if (Socket->SharedData->AsyncEvents & FD_CONNECT)
2371 {
2373 }
2374
2376 IOSB->Status = STATUS_PENDING;
2377
2378 /* Send IOCTL */
2380 lpOverlapped->hEvent,
2381 NULL,
2382 lpOverlapped->hEvent ? NULL : lpOverlapped,
2383 IOSB,
2385 ConnectInfo,
2386 FIELD_OFFSET(AFD_SUPER_CONNECT_INFO, RemoteAddress.Address[0].Address[SocketDataLength]),
2387 lpSendBuffer,
2388 dwSendDataLength);
2389
2391
2392 return Status == STATUS_SUCCESS;
2393}
#define ARRAYSIZE(a)
Definition: cat.c:25
struct _AFD_SUPER_CONNECT_INFO * PAFD_SUPER_CONNECT_INFO
#define IOCTL_AFD_SUPER_CONNECT
Definition: shared.h:359
TRANSPORT_ADDRESS RemoteAddress
Definition: shared.h:137
#define XP1_CONNECTIONLESS
Definition: winsock2.h:430

Referenced by WSPIoctl().

◆ WSPDuplicateSocket()

INT WSPAPI WSPDuplicateSocket ( IN SOCKET  Handle,
IN DWORD  dwProcessId,
OUT LPWSAPROTOCOL_INFOW  lpProtocolInfo,
OUT LPINT  lpErrno 
)

Definition at line 449 of file dllmain.c.

454{
455 HANDLE hProcess, hDuplicatedSharedData, hDuplicatedHandle;
456 PSOCKET_INFORMATION Socket;
457 PSOCK_SHARED_INFO pSharedData, pOldSharedData;
458 BOOL bDuplicated;
459
460 if (Handle == INVALID_SOCKET)
462 Socket = GetSocketStructure(Handle);
463 if( !Socket )
464 {
465 if( lpErrno )
466 *lpErrno = WSAENOTSOCK;
467 return SOCKET_ERROR;
468 }
471
472 /* It is a not yet duplicated socket, so map the memory, copy the SharedData and free heap */
474 {
476 NULL,
478 0,
479 (sizeof(SOCK_SHARED_INFO) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1),
480 NULL);
483 pSharedData = MapViewOfFile(Socket->SharedDataHandle,
485 0,
486 0,
487 sizeof(SOCK_SHARED_INFO));
488
489 RtlCopyMemory(pSharedData, Socket->SharedData, sizeof(SOCK_SHARED_INFO));
490 pOldSharedData = Socket->SharedData;
491 Socket->SharedData = pSharedData;
492 HeapFree(GlobalHeap, 0, pOldSharedData);
493 }
494 /* Duplicate the handles for the new process */
495 bDuplicated = DuplicateHandle(GetCurrentProcess(),
496 Socket->SharedDataHandle,
497 hProcess,
498 (LPHANDLE)&hDuplicatedSharedData,
499 0,
500 FALSE,
502 if (!bDuplicated)
503 {
506 }
507 bDuplicated = DuplicateHandle(GetCurrentProcess(),
508 (HANDLE)Socket->Handle,
509 hProcess,
510 (LPHANDLE)&hDuplicatedHandle,
511 0,
512 FALSE,
515 if( !bDuplicated )
517
518
519 if (!lpProtocolInfo)
521
522 RtlCopyMemory(lpProtocolInfo, &Socket->ProtocolInfo, sizeof(*lpProtocolInfo));
523
524 lpProtocolInfo->iAddressFamily = Socket->SharedData->AddressFamily;
525 lpProtocolInfo->iProtocol = Socket->SharedData->Protocol;
526 lpProtocolInfo->iSocketType = Socket->SharedData->SocketType;
527 lpProtocolInfo->dwServiceFlags3 = HandleToUlong(hDuplicatedSharedData);
528 lpProtocolInfo->dwServiceFlags4 = HandleToUlong(hDuplicatedHandle);
529
530 if( lpErrno )
531 *lpErrno = NO_ERROR;
532
533 return NO_ERROR;
534}
#define HandleToUlong(h)
Definition: basetsd.h:73
#define GetCurrentProcess()
Definition: compat.h:759
#define MapViewOfFile
Definition: compat.h:745
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
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1274
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PROCESS_DUP_HANDLE
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define SEC_COMMIT
Definition: mmtypes.h:100
#define PAGE_READWRITE
Definition: nt_native.h:1307
_In_ DWORD dwProcessId
Definition: shlwapi.h:193
#define CreateFileMapping
Definition: winbase.h:3473
#define FILE_MAP_ALL_ACCESS
Definition: winbase.h:159
#define DUPLICATE_SAME_ACCESS

Referenced by WSPStartup().

◆ WSPGetAcceptExSockaddrs()

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 at line 1934 of file dllmain.c.

1943{
1944 /* AFD_SUPER_ACCEPT outputs receive data + local address + local address length + remote address + remote address length */
1945 /* Length is located 2 bytes before address length */
1946 BYTE* LocalAddress = (BYTE *)lpOutputBuffer + dwReceiveDataLength;
1948 {
1949 *LocalSockaddr = (struct sockaddr *)LocalAddress;
1951 }
1952
1954 {
1958 }
1959}
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int UINT
Definition: sysinfo.c:13
_In_ DWORD _In_ DWORD _In_ DWORD _Outptr_result_bytebuffer_ LocalSockaddrLength struct sockaddr ** LocalSockaddr
Definition: mswsock.h:114
_In_ DWORD _In_ DWORD _In_ DWORD _Outptr_result_bytebuffer_ LocalSockaddrLength struct sockaddr _Out_ LPINT LocalSockaddrLength
Definition: mswsock.h:115
_In_ DWORD _In_ DWORD _In_ DWORD _Outptr_result_bytebuffer_ LocalSockaddrLength struct sockaddr _Out_ LPINT _Outptr_result_bytebuffer_ RemoteSockaddrLength struct sockaddr ** RemoteSockaddr
Definition: mswsock.h:116
_In_ DWORD _In_ DWORD _In_ DWORD _Outptr_result_bytebuffer_ LocalSockaddrLength struct sockaddr _Out_ LPINT _Outptr_result_bytebuffer_ RemoteSockaddrLength struct sockaddr _Out_ LPINT RemoteSockaddrLength
Definition: mswsock.h:117
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR LocalAddress
Definition: wsk.h:171
unsigned char BYTE
Definition: xxhash.c:193

Referenced by WSPIoctl().

◆ WSPGetPeerName()

INT WSPAPI WSPGetPeerName ( IN SOCKET  s,
OUT LPSOCKADDR  Name,
IN OUT LPINT  NameLength,
OUT LPINT  lpErrno 
)

Definition at line 2579 of file dllmain.c.

2583{
2584 IO_STATUS_BLOCK IOSB;
2585 ULONG TdiAddressSize;
2586 PTRANSPORT_ADDRESS SocketAddress;
2587 PSOCKET_INFORMATION Socket = NULL;
2590
2591 /* Get the Socket Structure associate to this Socket*/
2592 Socket = GetSocketStructure(s);
2593 if (!Socket)
2594 {
2595 if (lpErrno) *lpErrno = WSAENOTSOCK;
2596 return SOCKET_ERROR;
2597 }
2598
2599 if (Socket->SharedData->State != SocketConnected)
2600 {
2601 if (lpErrno) *lpErrno = WSAENOTCONN;
2602 return SOCKET_ERROR;
2603 }
2604
2605 if (!Name || !NameLength)
2606 {
2607 if (lpErrno) *lpErrno = WSAEFAULT;
2608 return SOCKET_ERROR;
2609 }
2610
2613 NULL,
2615 FALSE);
2616
2617 if( !NT_SUCCESS(Status) )
2618 return SOCKET_ERROR;
2619
2620 /* Allocate a buffer for the address */
2621 TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress;
2622 SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2623
2624 if ( SocketAddress == NULL )
2625 {
2626 NtClose( SockEvent );
2627 if (lpErrno) *lpErrno = WSAENOBUFS;
2628 return SOCKET_ERROR;
2629 }
2630
2631 /* Send IOCTL */
2633 SockEvent,
2634 NULL,
2635 NULL,
2636 &IOSB,
2638 NULL,
2639 0,
2640 SocketAddress,
2641 TdiAddressSize);
2642
2643 /* Wait for return */
2644 if (Status == STATUS_PENDING)
2645 {
2647 Status = IOSB.Status;
2648 }
2649
2650 NtClose( SockEvent );
2651
2652 if (NT_SUCCESS(Status))
2653 {
2654 if (*NameLength >= Socket->SharedData->SizeOfRemoteAddress)
2655 {
2656 Name->sa_family = SocketAddress->Address[0].AddressType;
2657 RtlCopyMemory (Name->sa_data,
2658 SocketAddress->Address[0].Address,
2659 SocketAddress->Address[0].AddressLength);
2660 *NameLength = Socket->SharedData->SizeOfRemoteAddress;
2661 TRACE("NameLength %d Address: %x Port %x\n",
2662 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2663 ((struct sockaddr_in *)Name)->sin_port);
2664 HeapFree(GlobalHeap, 0, SocketAddress);
2665 return 0;
2666 }
2667 else
2668 {
2669 HeapFree(GlobalHeap, 0, SocketAddress);
2670 if (lpErrno) *lpErrno = WSAEFAULT;
2671 return SOCKET_ERROR;
2672 }
2673 }
2674
2675 HeapFree(GlobalHeap, 0, SocketAddress);
2676
2677 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2678}
LPWSTR Name
Definition: desk.c:124
GLdouble s
Definition: gl.h:2039
#define IOCTL_AFD_GET_PEER_NAME
Definition: shared.h:309
struct _TRANSPORT_ADDRESS TRANSPORT_ADDRESS

Referenced by WSPStartup().

◆ WSPGetSockName()

INT WSPAPI WSPGetSockName ( IN SOCKET  Handle,
OUT LPSOCKADDR  Name,
IN OUT LPINT  NameLength,
OUT LPINT  lpErrno 
)

Definition at line 2477 of file dllmain.c.

2481{
2482 IO_STATUS_BLOCK IOSB;
2483 ULONG TdiAddressSize;
2484 PTDI_ADDRESS_INFO TdiAddress;
2485 PTRANSPORT_ADDRESS SocketAddress;
2486 PSOCKET_INFORMATION Socket = NULL;
2489
2490 /* Get the Socket Structure associate to this Socket*/
2491 Socket = GetSocketStructure(Handle);
2492 if (!Socket)
2493 {
2494 if (lpErrno) *lpErrno = WSAENOTSOCK;
2495 return SOCKET_ERROR;
2496 }
2497
2498 if (!Name || !NameLength)
2499 {
2500 if (lpErrno) *lpErrno = WSAEFAULT;
2501 return SOCKET_ERROR;
2502 }
2503
2506 NULL,
2508 FALSE);
2509
2510 if( !NT_SUCCESS(Status) )
2511 return SOCKET_ERROR;
2512
2513 /* Allocate a buffer for the address */
2514 TdiAddressSize =
2516 TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2517
2518 if ( TdiAddress == NULL )
2519 {
2520 NtClose( SockEvent );
2521 if (lpErrno) *lpErrno = WSAENOBUFS;
2522 return SOCKET_ERROR;
2523 }
2524
2525 SocketAddress = &TdiAddress->Address;
2526
2527 /* Send IOCTL */
2529 SockEvent,
2530 NULL,
2531 NULL,
2532 &IOSB,
2534 NULL,
2535 0,
2536 TdiAddress,
2537 TdiAddressSize);
2538
2539 /* Wait for return */
2540 if (Status == STATUS_PENDING)
2541 {
2543 Status = IOSB.Status;
2544 }
2545
2546 NtClose( SockEvent );
2547
2548 if (NT_SUCCESS(Status))
2549 {
2550 if (*NameLength >= Socket->SharedData->SizeOfLocalAddress)
2551 {
2552 Name->sa_family = SocketAddress->Address[0].AddressType;
2553 RtlCopyMemory (Name->sa_data,
2554 SocketAddress->Address[0].Address,
2555 SocketAddress->Address[0].AddressLength);
2556 *NameLength = Socket->SharedData->SizeOfLocalAddress;
2557 TRACE("NameLength %d Address: %x Port %x\n",
2558 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2559 ((struct sockaddr_in *)Name)->sin_port);
2560 HeapFree(GlobalHeap, 0, TdiAddress);
2561 return 0;
2562 }
2563 else
2564 {
2565 HeapFree(GlobalHeap, 0, TdiAddress);
2566 if (lpErrno) *lpErrno = WSAEFAULT;
2567 return SOCKET_ERROR;
2568 }
2569 }
2570
2571 HeapFree(GlobalHeap, 0, TdiAddress);
2572
2573 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2574}
#define IOCTL_AFD_GET_SOCK_NAME
Definition: shared.h:307
TRANSPORT_ADDRESS Address
Definition: tdi.h:388

Referenced by WSPStartup().

◆ WSPGetSockOpt()

INT WSPAPI WSPGetSockOpt ( IN SOCKET  Handle,
IN INT  Level,
IN INT  OptionName,
OUT CHAR FAR *  OptionValue,
IN OUT LPINT  OptionLength,
OUT LPINT  lpErrno 
)

Definition at line 2925 of file dllmain.c.

2931{
2932 PSOCKET_INFORMATION Socket = NULL;
2933 PVOID Buffer;
2935 BOOL BoolBuffer;
2936 DWORD DwordBuffer;
2937 INT Errno;
2938
2939 TRACE("Called\n");
2940
2941 /* Get the Socket Structure associate to this Socket*/
2942 Socket = GetSocketStructure(Handle);
2943 if (Socket == NULL)
2944 {
2945 if (lpErrno) *lpErrno = WSAENOTSOCK;
2946 return SOCKET_ERROR;
2947 }
2948 if (!OptionLength || !OptionValue)
2949 {
2950 if (lpErrno) *lpErrno = WSAEFAULT;
2951 return SOCKET_ERROR;
2952 }
2953
2954 switch (Level)
2955 {
2956 case SOL_SOCKET:
2957 switch (OptionName)
2958 {
2959 case SO_TYPE:
2960 Buffer = &Socket->SharedData->SocketType;
2961 BufferSize = sizeof(INT);
2962 break;
2963
2964 case SO_RCVBUF:
2966 BufferSize = sizeof(ULONG);
2967 break;
2968
2969 case SO_SNDBUF:
2971 BufferSize = sizeof(ULONG);
2972 break;
2973
2974 case SO_ACCEPTCONN:
2975 BoolBuffer = Socket->SharedData->Listening;
2976 Buffer = &BoolBuffer;
2977 BufferSize = sizeof(BOOL);
2978 break;
2979
2980 case SO_BROADCAST:
2981 BoolBuffer = Socket->SharedData->Broadcast;
2982 Buffer = &BoolBuffer;
2983 BufferSize = sizeof(BOOL);
2984 break;
2985
2986 case SO_DEBUG:
2987 BoolBuffer = Socket->SharedData->Debug;
2988 Buffer = &BoolBuffer;
2989 BufferSize = sizeof(BOOL);
2990 break;
2991
2992 case SO_DONTLINGER:
2993 BoolBuffer = (Socket->SharedData->LingerData.l_onoff == 0);
2994 Buffer = &BoolBuffer;
2995 BufferSize = sizeof(BOOL);
2996 break;
2997
2998 case SO_LINGER:
2999 if (Socket->SharedData->SocketType == SOCK_DGRAM)
3000 {
3001 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
3002 return SOCKET_ERROR;
3003 }
3004 Buffer = &Socket->SharedData->LingerData;
3005 BufferSize = sizeof(struct linger);
3006 break;
3007
3008 case SO_OOBINLINE:
3009 BoolBuffer = (Socket->SharedData->OobInline != 0);
3010 Buffer = &BoolBuffer;
3011 BufferSize = sizeof(BOOL);
3012 break;
3013
3014 case SO_KEEPALIVE:
3015 case SO_DONTROUTE:
3016 /* These guys go directly to the helper */
3017 goto SendToHelper;
3018
3020 BoolBuffer = (Socket->SharedData->UseDelayedAcceptance != 0);
3021 Buffer = &BoolBuffer;
3022 BufferSize = sizeof(BOOL);
3023 break;
3024
3025 case SO_REUSEADDR:
3026 BoolBuffer = (Socket->SharedData->ReuseAddresses != 0);
3027 Buffer = &BoolBuffer;
3028 BufferSize = sizeof(BOOL);
3029 break;
3030
3032 BoolBuffer = (Socket->SharedData->ExclusiveAddressUse != 0);
3033 Buffer = &BoolBuffer;
3034 BufferSize = sizeof(BOOL);
3035 break;
3036
3037 case SO_ERROR:
3038 Buffer = &Socket->SharedData->SocketLastError;
3039 BufferSize = sizeof(INT);
3040 break;
3041
3042 case SO_CONNECT_TIME:
3043 if (Socket->SharedData->ConnectTime)
3044 DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
3045 else
3046 DwordBuffer = -1;
3047 Buffer = &DwordBuffer;
3048 BufferSize = sizeof(DWORD);
3049 break;
3050
3051 case SO_SNDTIMEO:
3052 Buffer = &Socket->SharedData->SendTimeout;
3053 BufferSize = sizeof(DWORD);
3054 break;
3055 case SO_RCVTIMEO:
3056 Buffer = &Socket->SharedData->RecvTimeout;
3057 BufferSize = sizeof(DWORD);
3058 break;
3059 case SO_PROTOCOL_INFOW:
3060 Buffer = &Socket->ProtocolInfo;
3061 BufferSize = sizeof(Socket->ProtocolInfo);
3062 break;
3063
3064 case SO_GROUP_ID:
3065 case SO_GROUP_PRIORITY:
3066 case SO_MAX_MSG_SIZE:
3067
3068 default:
3069 DbgPrint("MSAFD: Get unknown optname %x\n", OptionName);
3070 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
3071 return SOCKET_ERROR;
3072 }
3073
3074 if (*OptionLength < BufferSize)
3075 {
3076 if (lpErrno) *lpErrno = WSAEFAULT;
3077 *OptionLength = BufferSize;
3078 return SOCKET_ERROR;
3079 }
3080 RtlCopyMemory(OptionValue, Buffer, BufferSize);
3081
3082 return 0;
3083
3084 default:
3085 if (lpErrno) *lpErrno = WSAEINVAL;
3086 return SOCKET_ERROR;
3087 }
3088
3089SendToHelper:
3090 Errno = Socket->HelperData->WSHGetSocketInformation(Socket->HelperContext,
3091 Handle,
3092 Socket->TdiAddressHandle,
3093 Socket->TdiConnectionHandle,
3094 Level,
3095 OptionName,
3096 OptionValue,
3097 (LPINT)OptionLength);
3098 if (lpErrno) *lpErrno = Errno;
3099 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
3100}
#define BufferSize
Definition: mmc.h:75
_In_ ULONG BufferSize
Definition: dispmprt.h:490
_In_ ULONG _In_ UCHAR Level
Definition: dispmprt.h:1329
#define DbgPrint
Definition: hal.h:12
int * LPINT
Definition: minwindef.h:151
#define SO_CONNECT_TIME
Definition: mswsock.h:36
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
#define INT
Definition: polytest.cpp:20
PWSH_GET_SOCKET_INFORMATION WSHGetSocketInformation
Definition: helpers.h:26
BOOLEAN Debug
Definition: shared.h:399
ULONG RecvTimeout
Definition: shared.h:392
BOOLEAN OobInline
Definition: shared.h:400
ULONG SizeOfSendBuffer
Definition: shared.h:394
ULONG SizeOfRecvBuffer
Definition: shared.h:393
ULONG SendTimeout
Definition: shared.h:391
#define WSAENOPROTOOPT
Definition: winerror.h:2858
#define SO_PROTOCOL_INFOW
Definition: winsock2.h:243
#define SO_ERROR
Definition: winsock.h:188
#define SO_KEEPALIVE
Definition: winsock.h:175
#define SO_RCVBUF
Definition: winsock.h:183
#define SO_OOBINLINE
Definition: winsock.h:180
#define SO_DONTROUTE
Definition: winsock.h:176
#define SO_ACCEPTCONN
Definition: winsock.h:173
#define SOCK_DGRAM
Definition: winsock.h:330
#define SO_LINGER
Definition: winsock.h:179
#define SO_REUSEADDR
Definition: winsock.h:174
#define SO_TYPE
Definition: winsock.h:189
#define SOL_SOCKET
Definition: winsock.h:392
#define SO_DEBUG
Definition: winsock.h:172
#define SO_SNDTIMEO
Definition: winsock.h:186
#define SO_BROADCAST
Definition: winsock.h:177
#define SO_DONTLINGER
Definition: winsock.h:181
#define SO_RCVTIMEO
Definition: winsock.h:187
#define SO_SNDBUF
Definition: winsock.h:182
#define SO_CONDITIONAL_ACCEPT
Definition: ws2def.h:121
#define SO_EXCLUSIVEADDRUSE
Definition: ws2def.h:105
#define SO_GROUP_ID
Definition: ws2def.h:117
#define SO_MAX_MSG_SIZE
Definition: ws2def.h:119
#define SO_GROUP_PRIORITY
Definition: ws2def.h:118

Referenced by WSPStartup().

◆ WSPIoctl()

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 at line 2682 of file dllmain.c.

2693{
2694 PSOCKET_INFORMATION Socket = NULL;
2695 BOOL NeedsCompletion = lpOverlapped != NULL;
2696 BOOLEAN NonBlocking;
2697 INT Errno = NO_ERROR, Ret = SOCKET_ERROR;
2698 DWORD cbRet = 0;
2699
2700 /* Get the Socket Structure associate to this Socket*/
2701 Socket = GetSocketStructure(Handle);
2702 if (!Socket)
2703 {
2704 if(lpErrno)
2705 *lpErrno = WSAENOTSOCK;
2706 return SOCKET_ERROR;
2707 }
2708
2709 if (!lpcbBytesReturned && !lpOverlapped)
2710 {
2711 if(lpErrno)
2712 *lpErrno = WSAEFAULT;
2713 return SOCKET_ERROR;
2714 }
2715
2716 switch( dwIoControlCode )
2717 {
2718 case FIONBIO:
2719 if( cbInBuffer < sizeof(INT) || IS_INTRESOURCE(lpvInBuffer) )
2720 {
2721 Errno = WSAEFAULT;
2722 break;
2723 }
2724 NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
2725 /* Don't allow to go in blocking mode if WSPAsyncSelect or WSPEventSelect is pending */
2726 if (!NonBlocking)
2727 {
2728 /* If there is an WSPAsyncSelect pending, fail with WSAEINVAL */
2729 if (Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents))
2730 {
2731 Errno = WSAEINVAL;
2732 break;
2733 }
2734 /* If there is an WSPEventSelect pending, fail with WSAEINVAL */
2735 if (Socket->NetworkEvents)
2736 {
2737 Errno = WSAEINVAL;
2738 break;
2739 }
2740 }
2741 Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
2742 NeedsCompletion = FALSE;
2743 Errno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL, lpOverlapped, lpCompletionRoutine);
2744 if (Errno == NO_ERROR)
2745 Ret = NO_ERROR;
2746 break;
2747 case FIONREAD:
2748 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2749 {
2750 cbRet = sizeof(ULONG);
2751 Errno = WSAEFAULT;
2752 break;
2753 }
2754 if (cbOutBuffer < sizeof(ULONG))
2755 {
2756 Errno = WSAEINVAL;
2757 break;
2758 }
2759 NeedsCompletion = FALSE;
2760 Errno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL, lpOverlapped, lpCompletionRoutine);
2761 if (Errno == NO_ERROR)
2762 {
2763 cbRet = sizeof(ULONG);
2764 Ret = NO_ERROR;
2765 }
2766 break;
2767 case SIOCATMARK:
2768 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2769 {
2770 cbRet = sizeof(BOOL);
2771 Errno = WSAEFAULT;
2772 break;
2773 }
2774 if (cbOutBuffer < sizeof(BOOL))
2775 {
2776 Errno = WSAEINVAL;
2777 break;
2778 }
2779 if (Socket->SharedData->SocketType != SOCK_STREAM)
2780 {
2781 Errno = WSAEINVAL;
2782 break;
2783 }
2784
2785 /* FIXME: Return false if OOBINLINE is true for now
2786 We should MSG_PEEK|MSG_OOB check with driver
2787 */
2788 *(BOOL*)lpvOutBuffer = !Socket->SharedData->OobInline;
2789
2790 cbRet = sizeof(BOOL);
2791 Errno = NO_ERROR;
2792 Ret = NO_ERROR;
2793 break;
2795 if (cbOutBuffer == 0)
2796 {
2797 cbRet = sizeof(PVOID);
2798 Errno = WSAEFAULT;
2799 break;
2800 }
2801
2802 if (cbInBuffer < sizeof(GUID) ||
2803 cbOutBuffer < sizeof(PVOID))
2804 {
2805 Errno = WSAEINVAL;
2806 break;
2807 }
2808
2809 {
2810 GUID AcceptExGUID = WSAID_ACCEPTEX;
2811 GUID ConnectExGUID = WSAID_CONNECTEX;
2812 GUID DisconnectExGUID = WSAID_DISCONNECTEX;
2813 GUID GetAcceptExSockaddrsGUID = WSAID_GETACCEPTEXSOCKADDRS;
2814
2815 if (IsEqualGUID(&AcceptExGUID, lpvInBuffer))
2816 {
2817 *((PVOID *)lpvOutBuffer) = WSPAcceptEx;
2818 cbRet = sizeof(PVOID);
2819 Errno = NO_ERROR;
2820 Ret = NO_ERROR;
2821 }
2822 else if (IsEqualGUID(&ConnectExGUID, lpvInBuffer))
2823 {
2824 *((PVOID *)lpvOutBuffer) = WSPConnectEx;
2825 cbRet = sizeof(PVOID);
2826 Errno = NO_ERROR;
2827 Ret = NO_ERROR;
2828 }
2829 else if (IsEqualGUID(&DisconnectExGUID, lpvInBuffer))
2830 {
2831 *((PVOID *)lpvOutBuffer) = WSPDisconnectEx;
2832 cbRet = sizeof(PVOID);
2833 Errno = NO_ERROR;
2834 Ret = NO_ERROR;
2835 }
2836 else if (IsEqualGUID(&GetAcceptExSockaddrsGUID, lpvInBuffer))
2837 {
2838 *((PVOID *)lpvOutBuffer) = WSPGetAcceptExSockaddrs;
2839 cbRet = sizeof(PVOID);
2840 Errno = NO_ERROR;
2841 Ret = NO_ERROR;
2842 }
2843 else
2844 {
2845 ERR("Querying unknown extension function: %x\n", ((GUID*)lpvInBuffer)->Data1);
2846 Errno = WSAEOPNOTSUPP;
2847 }
2848 }
2849
2850 break;
2852 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2853 {
2854 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2855 Errno = WSAEFAULT;
2856 break;
2857 }
2858 if (cbOutBuffer < sizeof(INT))
2859 {
2860 Errno = WSAEINVAL;
2861 break;
2862 }
2863
2864 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2865
2866 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->iAddressCount = 1;
2867
2868 if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress)))
2869 {
2870 Errno = WSAEFAULT;
2871 break;
2872 }
2873
2874 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->SharedData->WSLocalAddress);
2875 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->SharedData->WSLocalAddress;
2876
2877 Errno = NO_ERROR;
2878 Ret = NO_ERROR;
2879 break;
2880 default:
2881 Errno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
2882 Handle,
2883 Socket->TdiAddressHandle,
2884 Socket->TdiConnectionHandle,
2886 lpvInBuffer,
2887 cbInBuffer,
2888 lpvOutBuffer,
2889 cbOutBuffer,
2890 &cbRet,
2892 lpCompletionRoutine,
2893 &NeedsCompletion);
2894
2895 if (Errno == NO_ERROR)
2896 Ret = NO_ERROR;
2897 break;
2898 }
2899 if (lpOverlapped && NeedsCompletion)
2900 {
2901 lpOverlapped->Internal = Errno;
2902 lpOverlapped->InternalHigh = cbRet;
2903 if (lpCompletionRoutine != NULL)
2904 {
2905 lpCompletionRoutine(Errno, cbRet, lpOverlapped, 0);
2906 }
2907 if (lpOverlapped->hEvent)
2908 SetEvent(lpOverlapped->hEvent);
2910 {
2911 ERR("PostQueuedCompletionStatus failed %d\n", GetLastError());
2912 }
2913 return NO_ERROR;
2914 }
2915 if (lpErrno)
2916 *lpErrno = Errno;
2917 if (lpcbBytesReturned)
2918 *lpcbBytesReturned = cbRet;
2919 return Ret;
2920}
unsigned char BOOLEAN
Definition: actypes.h:127
#define IS_INTRESOURCE(x)
Definition: loader.c:613
BOOL WSPAPI WSPConnectEx(_In_ SOCKET Handle, _In_ const struct sockaddr *SocketAddress, _In_ int SocketAddressLength, _In_ PVOID lpSendBuffer, _In_ DWORD dwSendDataLength, _Out_ LPDWORD lpdwBytesSent, _Inout_ LPOVERLAPPED lpOverlapped)
Definition: dllmain.c:2298
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: dllmain.c:1934
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:3838
BOOL WSPAPI WSPAcceptEx(_In_ SOCKET sListenSocket, _In_ SOCKET sAcceptSocket, _Out_ PVOID lpOutputBuffer, _In_ DWORD dwReceiveDataLength, _In_ DWORD dwLocalAddressLength, _In_ DWORD dwRemoteAddressLength, _Out_ LPDWORD lpdwBytesReceived, _Inout_ LPOVERLAPPED lpOverlapped)
Definition: dllmain.c:1847
BOOL WSPAPI WSPDisconnectEx(IN SOCKET hSocket, IN LPOVERLAPPED lpOverlapped, IN DWORD dwFlags, IN DWORD reserved)
Definition: stubs.c:58
#define SOCK_STREAM
Definition: tcpip.h:118
BOOL WINAPI PostQueuedCompletionStatus(IN HANDLE CompletionHandle, IN DWORD dwNumberOfBytesTransferred, IN ULONG_PTR dwCompletionKey, IN LPOVERLAPPED lpOverlapped)
Definition: iocompl.c:192
#define WSAID_GETACCEPTEXSOCKADDRS
Definition: mswsock.h:77
#define WSAID_ACCEPTEX
Definition: mswsock.h:74
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define AFD_INFO_RECEIVE_CONTENT_SIZE
Definition: shared.h:204
#define AFD_INFO_BLOCKING_MODE
Definition: shared.h:199
PWSH_IOCTL WSHIoctl
Definition: helpers.h:33
LONG NetworkEvents
Definition: msafd.h:58
SOCKADDR WSLocalAddress
Definition: shared.h:423
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
uint32_t * PULONG
Definition: typedefs.h:59
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ DWORD dwIoControlCode
Definition: winddi.h:1700
#define SIOCATMARK
Definition: winsock.h:247
#define FIONREAD
Definition: winsock.h:241
#define FIONBIO
Definition: winsock.h:143
#define SIO_ADDRESS_LIST_QUERY
Definition: ws2def.h:177
struct _SOCKET_ADDRESS_LIST SOCKET_ADDRESS_LIST
#define SIO_GET_EXTENSION_FUNCTION_POINTER
Definition: ws2def.h:167

Referenced by WSPStartup().

◆ WSPListen()

int WSPAPI WSPListen ( SOCKET  Handle,
int  Backlog,
LPINT  lpErrno 
)

Definition at line 998 of file dllmain.c.

1001{
1002 IO_STATUS_BLOCK IOSB;
1003 AFD_LISTEN_DATA ListenData;
1004 PSOCKET_INFORMATION Socket = NULL;
1007
1008 /* Get the Socket Structure associate to this Socket*/
1009 Socket = GetSocketStructure(Handle);
1010 if (!Socket)
1011 {
1012 if (lpErrno) *lpErrno = WSAENOTSOCK;
1013 return SOCKET_ERROR;
1014 }
1015
1016 if (Socket->SharedData->Listening)
1017 return NO_ERROR;
1018
1021 NULL,
1023 FALSE);
1024
1025 if( !NT_SUCCESS(Status) )
1026 return SOCKET_ERROR;
1027
1028 /* Set Up Listen Structure */
1029 ListenData.UseSAN = FALSE;
1031 ListenData.Backlog = Backlog;
1032
1033 /* Send IOCTL */
1035 SockEvent,
1036 NULL,
1037 NULL,
1038 &IOSB,
1040 &ListenData,
1041 sizeof(ListenData),
1042 NULL,
1043 0);
1044
1045 /* Wait for return */
1046 if (Status == STATUS_PENDING)
1047 {
1049 Status = IOSB.Status;
1050 }
1051
1052 NtClose( SockEvent );
1053
1055 if (Status != STATUS_SUCCESS)
1056 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1057
1058 /* Set to Listening */
1059 Socket->SharedData->Listening = TRUE;
1060
1061 if (Socket->HelperEvents & WSH_NOTIFY_LISTEN)
1062 {
1063 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1064 Socket->Handle,
1065 Socket->TdiAddressHandle,
1066 Socket->TdiConnectionHandle,
1068
1069 if (Status)
1070 {
1071 if (lpErrno) *lpErrno = Status;
1072 return SOCKET_ERROR;
1073 }
1074 }
1075
1076 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1077}
#define IOCTL_AFD_START_LISTEN
Definition: shared.h:289
BOOLEAN UseSAN
Definition: shared.h:44
BOOLEAN UseDelayedAcceptance
Definition: shared.h:46
ULONG Backlog
Definition: shared.h:45
#define WSH_NOTIFY_LISTEN
Definition: wsahelp.h:11

Referenced by WSPStartup().

◆ WSPSelect()

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 at line 1082 of file dllmain.c.

1088{
1089 IO_STATUS_BLOCK IOSB;
1090 PAFD_POLL_INFO PollInfo;
1093 ULONG PollBufferSize;
1094 PVOID PollBuffer;
1095 ULONG i, j = 0, x;
1098 PSOCKET_INFORMATION Socket;
1099 SOCKET Handle;
1100 ULONG Events;
1101 fd_set selectfds;
1102
1103 /* Find out how many sockets we have, and how large the buffer needs
1104 * to be */
1105 FD_ZERO(&selectfds);
1106 if (readfds != NULL)
1107 {
1108 for (i = 0; i < readfds->fd_count; i++)
1109 {
1110 FD_SET(readfds->fd_array[i], &selectfds);
1111 }
1112 }
1113 if (writefds != NULL)
1114 {
1115 for (i = 0; i < writefds->fd_count; i++)
1116 {
1117 FD_SET(writefds->fd_array[i], &selectfds);
1118 }
1119 }
1120 if (exceptfds != NULL)
1121 {
1122 for (i = 0; i < exceptfds->fd_count; i++)
1123 {
1124 FD_SET(exceptfds->fd_array[i], &selectfds);
1125 }
1126 }
1127
1128 HandleCount = selectfds.fd_count;
1129
1130 if ( HandleCount == 0 )
1131 {
1132 WARN("No handles! Returning SOCKET_ERROR\n", HandleCount);
1133 if (lpErrno) *lpErrno = WSAEINVAL;
1134 return SOCKET_ERROR;
1135 }
1136
1137 PollBufferSize = sizeof(*PollInfo) + ((HandleCount - 1) * sizeof(AFD_HANDLE));
1138
1139 TRACE("HandleCount: %u BufferSize: %u\n", HandleCount, PollBufferSize);
1140
1141 /* Convert Timeout to NT Format */
1142 if (timeout == NULL)
1143 {
1144 Timeout.u.LowPart = -1;
1145 Timeout.u.HighPart = 0x7FFFFFFF;
1146 TRACE("Infinite timeout\n");
1147 }
1148 else
1149 {
1151 ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000), -10000);
1152 /* Negative timeouts are illegal. Since the kernel represents an
1153 * incremental timeout as a negative number, we check for a positive
1154 * result.
1155 */
1156 if (Timeout.QuadPart > 0)
1157 {
1158 if (lpErrno) *lpErrno = WSAEINVAL;
1159 return SOCKET_ERROR;
1160 }
1161 TRACE("Timeout: Orig %d.%06d kernel %d\n",
1162 timeout->tv_sec, timeout->tv_usec,
1163 Timeout.u.LowPart);
1164 }
1165
1168 NULL,
1170 FALSE);
1171
1172 if(!NT_SUCCESS(Status))
1173 {
1174 if (lpErrno)
1175 *lpErrno = WSAEFAULT;
1176
1177 ERR("NtCreateEvent failed, 0x%08x\n", Status);
1178 return SOCKET_ERROR;
1179 }
1180
1181 /* Allocate */
1182 PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
1183
1184 if (!PollBuffer)
1185 {
1186 if (lpErrno)
1187 *lpErrno = WSAEFAULT;
1189 return SOCKET_ERROR;
1190 }
1191
1192 PollInfo = (PAFD_POLL_INFO)PollBuffer;
1193
1194 RtlZeroMemory( PollInfo, PollBufferSize );
1195
1196 /* Number of handles for AFD to Check */
1197 PollInfo->Exclusive = FALSE;
1198 PollInfo->Timeout = Timeout;
1199
1200 for (i = 0; i < selectfds.fd_count; i++)
1201 {
1202 PollInfo->Handles[i].Handle = selectfds.fd_array[i];
1203 }
1204 if (readfds != NULL) {
1205 for (i = 0; i < readfds->fd_count; i++)
1206 {
1207 for (j = 0; j < HandleCount; j++)
1208 {
1209 if (PollInfo->Handles[j].Handle == readfds->fd_array[i])
1210 break;
1211 }
1212 if (j >= HandleCount)
1213 {
1214 ERR("Error while counting readfds %ld > %ld\n", j, HandleCount);
1215 if (lpErrno) *lpErrno = WSAEFAULT;
1216 HeapFree(GlobalHeap, 0, PollBuffer);
1218 return SOCKET_ERROR;
1219 }
1220 Socket = GetSocketStructure(readfds->fd_array[i]);
1221 if (!Socket)
1222 {
1223 ERR("Invalid socket handle provided in readfds %d\n", readfds->fd_array[i]);
1224 if (lpErrno) *lpErrno = WSAENOTSOCK;
1225 HeapFree(GlobalHeap, 0, PollBuffer);
1227 return SOCKET_ERROR;
1228 }
1229 PollInfo->Handles[j].Events |= AFD_EVENT_RECEIVE |
1234 //if (Socket->SharedData->OobInline != 0)
1235 // PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
1236 }
1237 }
1238 if (writefds != NULL)
1239 {
1240 for (i = 0; i < writefds->fd_count; i++)
1241 {
1242 for (j = 0; j < HandleCount; j++)
1243 {
1244 if (PollInfo->Handles[j].Handle == writefds->fd_array[i])
1245 break;
1246 }
1247 if (j >= HandleCount)
1248 {
1249 ERR("Error while counting writefds %ld > %ld\n", j, HandleCount);
1250 if (lpErrno) *lpErrno = WSAEFAULT;
1251 HeapFree(GlobalHeap, 0, PollBuffer);
1253 return SOCKET_ERROR;
1254 }
1255 Socket = GetSocketStructure(writefds->fd_array[i]);
1256 if (!Socket)
1257 {
1258 ERR("Invalid socket handle provided in writefds %d\n", writefds->fd_array[i]);
1259 if (lpErrno) *lpErrno = WSAENOTSOCK;
1260 HeapFree(GlobalHeap, 0, PollBuffer);
1262 return SOCKET_ERROR;
1263 }
1264 PollInfo->Handles[j].Handle = writefds->fd_array[i];
1265 PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
1266 if (Socket->SharedData->NonBlocking != 0)
1267 PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT;
1268 }
1269 }
1270 if (exceptfds != NULL)
1271 {
1272 for (i = 0; i < exceptfds->fd_count; i++)
1273 {
1274 for (j = 0; j < HandleCount; j++)
1275 {
1276 if (PollInfo->Handles[j].Handle == exceptfds->fd_array[i])
1277 break;
1278 }
1279 if (j > HandleCount)
1280 {
1281 ERR("Error while counting exceptfds %ld > %ld\n", j, HandleCount);
1282 if (lpErrno) *lpErrno = WSAEFAULT;
1283 HeapFree(GlobalHeap, 0, PollBuffer);
1285 return SOCKET_ERROR;
1286 }
1287 Socket = GetSocketStructure(exceptfds->fd_array[i]);
1288 if (!Socket)
1289 {
1290 TRACE("Invalid socket handle provided in exceptfds %d\n", exceptfds->fd_array[i]);
1291 if (lpErrno) *lpErrno = WSAENOTSOCK;
1292 HeapFree(GlobalHeap, 0, PollBuffer);
1294 return SOCKET_ERROR;
1295 }
1296 PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
1297 if (Socket->SharedData->OobInline == 0)
1298 PollInfo->Handles[j].Events |= AFD_EVENT_OOB_RECEIVE;
1299 if (Socket->SharedData->NonBlocking != 0)
1300 PollInfo->Handles[j].Events |= AFD_EVENT_CONNECT_FAIL;
1301 }
1302 }
1303
1304 PollInfo->HandleCount = HandleCount;
1305 PollBufferSize = FIELD_OFFSET(AFD_POLL_INFO, Handles) + PollInfo->HandleCount * sizeof(AFD_HANDLE);
1306
1307 /* Send IOCTL */
1309 SockEvent,
1310 NULL,
1311 NULL,
1312 &IOSB,
1314 PollInfo,
1315 PollBufferSize,
1316 PollInfo,
1317 PollBufferSize);
1318
1319 TRACE("DeviceIoControlFile => %x\n", Status);
1320
1321 /* Wait for Completion */
1322 if (Status == STATUS_PENDING)
1323 {
1325 Status = IOSB.Status;
1326 }
1327
1328 /* Clear the Structures */
1329 if( readfds )
1330 FD_ZERO(readfds);
1331 if( writefds )
1332 FD_ZERO(writefds);
1333 if( exceptfds )
1334 FD_ZERO(exceptfds);
1335
1336 /* Loop through return structure */
1337 HandleCount = PollInfo->HandleCount;
1338
1339 /* Return in FDSET Format */
1340 for (i = 0; i < HandleCount; i++)
1341 {
1342 Events = PollInfo->Handles[i].Events;
1343 Handle = PollInfo->Handles[i].Handle;
1344 for(x = 1; x; x<<=1)
1345 {
1346 Socket = GetSocketStructure(Handle);
1347 if (!Socket)
1348 {
1349 TRACE("Invalid socket handle found %d\n", Handle);
1350 if (lpErrno) *lpErrno = WSAENOTSOCK;
1351 HeapFree(GlobalHeap, 0, PollBuffer);
1353 return SOCKET_ERROR;
1354 }
1355 switch (Events & x)
1356 {
1357 case AFD_EVENT_RECEIVE:
1359 case AFD_EVENT_ABORT:
1360 case AFD_EVENT_ACCEPT:
1361 case AFD_EVENT_CLOSE:
1362 TRACE("Event %x on handle %x\n",
1363 Events,
1364 Handle);
1365 if ((Events & x) == AFD_EVENT_DISCONNECT || (Events & x) == AFD_EVENT_CLOSE)
1367 if ((Events & x) == AFD_EVENT_ABORT)
1369 if( readfds )
1370 FD_SET(Handle, readfds);
1371 break;
1372 case AFD_EVENT_SEND:
1373 TRACE("Event %x on handle %x\n",
1374 Events,
1375 Handle);
1376 if (writefds)
1377 FD_SET(Handle, writefds);
1378 break;
1379 case AFD_EVENT_CONNECT:
1380 TRACE("Event %x on handle %x\n",
1381 Events,
1382 Handle);
1383 if( writefds && Socket->SharedData->NonBlocking != 0 )
1384 FD_SET(Handle, writefds);
1385 break;
1387 TRACE("Event %x on handle %x\n",
1388 Events,
1389 Handle);
1390 if( readfds && Socket->SharedData->OobInline != 0 )
1391 FD_SET(Handle, readfds);
1392 if( exceptfds && Socket->SharedData->OobInline == 0 )
1393 FD_SET(Handle, exceptfds);
1394 break;
1396 TRACE("Event %x on handle %x\n",
1397 Events,
1398 Handle);
1399 if( exceptfds && Socket->SharedData->NonBlocking != 0 )
1400 FD_SET(Handle, exceptfds);
1401 break;
1402 }
1403 }
1404 }
1405
1406 HeapFree( GlobalHeap, 0, PollBuffer );
1407 NtClose( SockEvent );
1408
1409 if( lpErrno )
1410 {
1411 switch( IOSB.Status )
1412 {
1413 case STATUS_SUCCESS:
1414 case STATUS_TIMEOUT:
1415 *lpErrno = 0;
1416 break;
1417 default:
1418 *lpErrno = WSAEINVAL;
1419 break;
1420 }
1421 TRACE("*lpErrno = %x\n", *lpErrno);
1422 }
1423
1424 HandleCount = (readfds ? readfds->fd_count : 0) +
1425 (writefds && writefds != readfds ? writefds->fd_count : 0) +
1426 (exceptfds && exceptfds != readfds && exceptfds != writefds ? exceptfds->fd_count : 0);
1427
1428 TRACE("%d events\n", HandleCount);
1429
1430 return HandleCount;
1431}
HANDLE Events[3]
Definition: schedsvc.c:40
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
struct _AFD_POLL_INFO * PAFD_POLL_INFO
struct _AFD_HANDLE_ AFD_HANDLE
u_int fd_count
Definition: winsock.h:61
SOCKET fd_array[FD_SETSIZE]
Definition: winsock.h:62
Definition: dhcpd.h:248
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static ULONG HandleCount
Definition: uefidisk.c:67
NTSYSAPI LONGLONG WINAPI RtlEnlargedIntegerMultiply(INT, INT)

Referenced by select(), WSPAccept(), and WSPStartup().

◆ WSPSetSockOpt()

INT WSPAPI WSPSetSockOpt ( IN SOCKET  s,
IN INT  level,
IN INT  optname,
IN CONST CHAR FAR *  optval,
IN INT  optlen,
OUT LPINT  lpErrno 
)

Definition at line 3214 of file dllmain.c.

3221{
3222 PSOCKET_INFORMATION Socket;
3223 INT Errno;
3224
3225 /* Get the Socket Structure associate to this Socket*/
3226 Socket = GetSocketStructure(s);
3227 if (Socket == NULL)
3228 {
3229 if (lpErrno) *lpErrno = WSAENOTSOCK;
3230 return SOCKET_ERROR;
3231 }
3232 if (!optval && optlen)
3233 {
3234 if (lpErrno) *lpErrno = WSAEFAULT;
3235 return SOCKET_ERROR;
3236 }
3237
3238
3239 /* FIXME: We should handle some more cases here */
3240 if (level == SOL_SOCKET)
3241 {
3242 switch (optname)
3243 {
3244 case SO_BROADCAST:
3245 if (optlen < sizeof(BOOL))
3246 {
3247 if (lpErrno) *lpErrno = WSAEFAULT;
3248 return SOCKET_ERROR;
3249 }
3250 Socket->SharedData->Broadcast = (*optval != 0) ? 1 : 0;
3251 return NO_ERROR;
3252
3253 case SO_OOBINLINE:
3254 if (optlen < sizeof(BOOL))
3255 {
3256 if (lpErrno) *lpErrno = WSAEFAULT;
3257 return SOCKET_ERROR;
3258 }
3259 Socket->SharedData->OobInline = (*optval != 0) ? 1 : 0;
3260 return NO_ERROR;
3261
3262 case SO_DONTLINGER:
3263 if (optlen < sizeof(BOOL))
3264 {
3265 if (lpErrno) *lpErrno = WSAEFAULT;
3266 return SOCKET_ERROR;
3267 }
3268 Socket->SharedData->LingerData.l_onoff = (*optval != 0) ? 0 : 1;
3269 return NO_ERROR;
3270
3271 case SO_REUSEADDR:
3272 if (optlen < sizeof(BOOL))
3273 {
3274 if (lpErrno) *lpErrno = WSAEFAULT;
3275 return SOCKET_ERROR;
3276 }
3277 Socket->SharedData->ReuseAddresses = (*optval != 0) ? 1 : 0;
3278 return NO_ERROR;
3279
3281 if (optlen < sizeof(BOOL))
3282 {
3283 if (lpErrno) *lpErrno = WSAEFAULT;
3284 return SOCKET_ERROR;
3285 }
3286 Socket->SharedData->ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
3287 return NO_ERROR;
3288
3289 case SO_LINGER:
3290 if (optlen < sizeof(struct linger))
3291 {
3292 if (lpErrno) *lpErrno = WSAEFAULT;
3293 return SOCKET_ERROR;
3294 }
3296 optval,
3297 sizeof(struct linger));
3298 return NO_ERROR;
3299
3300 case SO_SNDBUF:
3301 if (optlen < sizeof(ULONG))
3302 {
3303 if (lpErrno) *lpErrno = WSAEFAULT;
3304 return SOCKET_ERROR;
3305 }
3306
3307 SetSocketInformation(Socket,
3309 NULL,
3310 (PULONG)optval,
3311 NULL,
3312 NULL,
3313 NULL);
3314 GetSocketInformation(Socket,
3316 NULL,
3317 &Socket->SharedData->SizeOfSendBuffer,
3318 NULL,
3319 NULL,
3320 NULL);
3321
3322 return NO_ERROR;
3323
3324 case SO_RCVBUF:
3325 if (optlen < sizeof(ULONG))
3326 {
3327 if (lpErrno) *lpErrno = WSAEFAULT;
3328 return SOCKET_ERROR;
3329 }
3330
3331 /* FIXME: We should not have to limit the packet receive buffer size like this. workaround for CORE-15804 */
3332 if (*(PULONG)optval > 0x2000)
3333 *(PULONG)optval = 0x2000;
3334
3335 SetSocketInformation(Socket,
3337 NULL,
3338 (PULONG)optval,
3339 NULL,
3340 NULL,
3341 NULL);
3342 GetSocketInformation(Socket,
3344 NULL,
3345 &Socket->SharedData->SizeOfRecvBuffer,
3346 NULL,
3347 NULL,
3348 NULL);
3349
3350 return NO_ERROR;
3351
3352 case SO_UPDATE_CONNECT_CONTEXT:
3354 return MsafdUpdateConnectionContext(s, lpErrno);
3355
3356 case SO_ERROR:
3357 if (optlen < sizeof(INT))
3358 {
3359 if (lpErrno) *lpErrno = WSAEFAULT;
3360 return SOCKET_ERROR;
3361 }
3362
3364 optval,
3365 sizeof(INT));
3366 return NO_ERROR;
3367
3368 case SO_SNDTIMEO:
3369 if (optlen < sizeof(DWORD))
3370 {
3371 if (lpErrno) *lpErrno = WSAEFAULT;
3372 return SOCKET_ERROR;
3373 }
3374
3376 optval,
3377 sizeof(DWORD));
3378 return NO_ERROR;
3379
3380 case SO_RCVTIMEO:
3381 if (optlen < sizeof(DWORD))
3382 {
3383 if (lpErrno) *lpErrno = WSAEFAULT;
3384 return SOCKET_ERROR;
3385 }
3386
3388 optval,
3389 sizeof(DWORD));
3390 return NO_ERROR;
3391
3392 case SO_KEEPALIVE:
3393 case SO_DONTROUTE:
3394 /* These go directly to the helper dll */
3395 goto SendToHelper;
3396
3397 default:
3398 /* Obviously this is a hack */
3399 ERR("MSAFD: Set unknown optname %x\n", optname);
3400 return NO_ERROR;
3401 }
3402 }
3403
3404SendToHelper:
3405 Errno = Socket->HelperData->WSHSetSocketInformation(Socket->HelperContext,
3406 s,
3407 Socket->TdiAddressHandle,
3408 Socket->TdiConnectionHandle,
3409 level,
3410 optname,
3411 (PCHAR)optval,
3412 optlen);
3413 if (lpErrno) *lpErrno = Errno;
3414 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
3415}
static INT NTAPI MsafdUpdateConnectionContext(_In_ SOCKET Handle, _Out_ LPINT lpErrno)
Definition: dllmain.c:3105
GLint level
Definition: gl.h:1546
#define SO_UPDATE_ACCEPT_CONTEXT
Definition: mswsock.h:35
#define AFD_INFO_SEND_WINDOW_SIZE
Definition: shared.h:202
#define AFD_INFO_RECEIVE_WINDOW_SIZE
Definition: shared.h:201
PWSH_SET_SOCKET_INFORMATION WSHSetSocketInformation
Definition: helpers.h:27
char * PCHAR
Definition: typedefs.h:51

Referenced by WSPStartup().

◆ WSPShutdown()

int WSPAPI WSPShutdown ( SOCKET  Handle,
int  HowTo,
LPINT  lpErrno 
)

Definition at line 2397 of file dllmain.c.

2401{
2402 IO_STATUS_BLOCK IOSB;
2403 AFD_DISCONNECT_INFO DisconnectInfo;
2404 PSOCKET_INFORMATION Socket = NULL;
2407
2408 TRACE("Called\n");
2409
2410 /* Get the Socket Structure associate to this Socket*/
2411 Socket = GetSocketStructure(Handle);
2412 if (!Socket)
2413 {
2414 if (lpErrno) *lpErrno = WSAENOTSOCK;
2415 return SOCKET_ERROR;
2416 }
2417
2420 NULL,
2422 FALSE);
2423
2424 if( !NT_SUCCESS(Status) )
2425 return SOCKET_ERROR;
2426
2427 /* Set AFD Disconnect Type */
2428 switch (HowTo)
2429 {
2430 case SD_RECEIVE:
2431 DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
2432 Socket->SharedData->ReceiveShutdown = TRUE;
2433 break;
2434 case SD_SEND:
2435 DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
2436 Socket->SharedData->SendShutdown = TRUE;
2437 break;
2438 case SD_BOTH:
2440 Socket->SharedData->ReceiveShutdown = TRUE;
2441 Socket->SharedData->SendShutdown = TRUE;
2442 break;
2443 }
2444
2445 DisconnectInfo.Timeout.QuadPart = -1000000LL;
2446
2447 /* Send IOCTL */
2449 SockEvent,
2450 NULL,
2451 NULL,
2452 &IOSB,
2454 &DisconnectInfo,
2455 sizeof(DisconnectInfo),
2456 NULL,
2457 0);
2458
2459 /* Wait for return */
2460 if (Status == STATUS_PENDING)
2461 {
2463 Status = IOSB.Status;
2464 }
2465
2466 TRACE("Ending\n");
2467
2468 NtClose( SockEvent );
2469
2471 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
2472}
#define AFD_DISCONNECT_RECV
Definition: shared.h:214
#define SD_BOTH
Definition: winsock.h:50
#define SD_SEND
Definition: winsock.h:49
#define SD_RECEIVE
Definition: winsock.h:48

Referenced by WSPStartup().

◆ WSPSocket()

SOCKET WSPAPI WSPSocket ( int  AddressFamily,
int  SocketType,
int  Protocol,
LPWSAPROTOCOL_INFOW  lpProtocolInfo,
GROUP  g,
DWORD  dwFlags,
LPINT  lpErrno 
)

Definition at line 48 of file dllmain.c.

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;
256 EABuffer->EaNameLength = AFD_PACKET_COMMAND_LENGTH;
257 RtlCopyMemory (EABuffer->EaName,
260 EABuffer->EaValueLength = SizeOfPacket;
261
262 /* Set up AFD Packet */
263 AfdPacket = (PAFD_CREATE_PACKET)(EABuffer->EaName + EABuffer->EaNameLength + 1);
264 AfdPacket->SizeOfTransportName = TransportName.Length;
265 RtlCopyMemory (AfdPacket->TransportName,
266 TransportName.Buffer,
267 TransportName.Length + sizeof(WCHAR));
268 AfdPacket->GroupID = g;
269
270 /* Set up Endpoint Flags */
271 if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS) != 0)
272 {
273 if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW))
274 {
275 /* Only RAW or UDP can be Connectionless */
277 goto error;
278 }
280 }
281
282 if ((Socket->SharedData->ServiceFlags1 & XP1_MESSAGE_ORIENTED) != 0)
283 {
284 if (SocketType == SOCK_STREAM)
285 {
286 if ((Socket->SharedData->ServiceFlags1 & XP1_PSEUDO_STREAM) == 0)
287 {
288 /* The Provider doesn't actually support Message Oriented Streams */
290 goto error;
291 }
292 }
294 }
295
297
302 {
303 if ((Socket->SharedData->ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0)
304 {
305 /* The Provider doesn't actually support Multipoint */
307 goto error;
308 }
310
312 {
315 {
316 /* The Provider doesn't support Control Planes, or you already gave a leaf */
318 goto error;
319 }
321 }
322
324 {
327 {
328 /* The Provider doesn't support Data Planes, or you already gave a leaf */
330 goto error;
331 }
333 }
334 }
335
336 /* Set up Object Attributes */
338 &DevName,
340 0,
341 0);
342
343 /* Create the Socket as asynchronous. That means we have to block
344 ourselves after every call to NtDeviceIoControlFile. This is
345 because the kernel doesn't support overlapping synchronous I/O
346 requests (made from multiple threads) at this time (Sep 2005) */
347 Status = NtCreateFile(&Sock,
349 &Object,
350 &IOSB,
351 NULL,
352 0,
355 0,
356 EABuffer,
357 SizeOfEA);
358
359 HeapFree(GlobalHeap, 0, EABuffer);
360
361 if (!NT_SUCCESS(Status))
362 {
363 ERR("Failed to open socket. Status 0x%08x\n", Status);
365 goto error;
366 }
367
368 /* Save Handle */
369 Socket->Handle = (SOCKET)Sock;
370
371 /* Save Group Info */
372 if (g != 0)
373 {
376 NULL,
377 NULL,
378 &GroupData,
379 NULL,
380 NULL);
381 Socket->SharedData->GroupID = GroupData.u.LowPart;
382 Socket->SharedData->GroupType = GroupData.u.HighPart;
383 }
384
385 /* Get Window Sizes and Save them */
386 GetSocketInformation (Socket,
388 NULL,
390 NULL,
391 NULL,
392 NULL);
393
394 GetSocketInformation (Socket,
396 NULL,
398 NULL,
399 NULL,
400 NULL);
401ok:
402
403 /* Save in Process Sockets List */
405 Socket->NextSocket = SocketListHead;
406 SocketListHead = Socket;
408
409 /* Create the Socket Context */
410 CreateContext(Socket);
411
412 /* Notify Winsock */
414
415 /* Return Socket Handle */
416 TRACE("Success %x\n", Sock);
417
418 return (SOCKET)Sock;
419
420error:
421 TRACE("Ending %x\n", Status);
422
423 if( SharedData )
424 {
425 UnmapViewOfFile(SharedData);
426 NtClose(UlongToHandle(lpProtocolInfo->dwServiceFlags3));
427 }
428 else
429 {
430 if( Socket && Socket->SharedData )
431 HeapFree(GlobalHeap, 0, Socket->SharedData);
432 }
433
434 if( Socket )
435 HeapFree(GlobalHeap, 0, Socket);
436
437 if( EABuffer )
438 HeapFree(GlobalHeap, 0, EABuffer);
439
440 if( lpErrno )
441 *lpErrno = Status;
442
443 return INVALID_SOCKET;
444}
#define InterlockedIncrement
Definition: armddk.h:53
#define UlongToHandle(ul)
Definition: basetsd.h:91
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
int CreateContext(PSOCKET_INFORMATION Socket)
Definition: dllmain.c:3983
#define IPPROTO_RAW
Definition: ip.h:193
#define IPPROTO_TCP
Definition: ip.h:197
#define IPPROTO_UDP
Definition: ip.h:198
#define UlongToPtr(u)
Definition: config.h:106
struct _FILE_FULL_EA_INFORMATION FILE_FULL_EA_INFORMATION
GLboolean GLboolean g
Definition: glext.h:6204
#define error(str)
Definition: mkdosfs.c:1605
IN PCO_ADDRESS_FAMILY AddressFamily
Definition: ndis.h:1906
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
struct _AFD_CREATE_PACKET * PAFD_CREATE_PACKET
#define AfdCommand
Definition: shared.h:12
#define AFD_PACKET_COMMAND_LENGTH
Definition: shared.h:11
#define AFD_ENDPOINT_RAW
Definition: shared.h:171
#define AFD_ENDPOINT_D_ROOT
Definition: shared.h:174
#define AFD_ENDPOINT_MULTIPOINT
Definition: shared.h:172
#define AFD_ENDPOINT_MESSAGE_ORIENTED
Definition: shared.h:170
struct _AFD_CREATE_PACKET AFD_CREATE_PACKET
#define AFD_ENDPOINT_CONNECTIONLESS
Definition: shared.h:169
#define AFD_ENDPOINT_C_ROOT
Definition: shared.h:173
#define AFD_INFO_GROUP_ID_TYPE
Definition: shared.h:203
DWORD EndpointFlags
Definition: shared.h:22
WCHAR TransportName[1]
Definition: shared.h:25
DWORD SizeOfTransportName
Definition: shared.h:24
BOOLEAN UseDelayedAcceptance
Definition: helpers.h:20
DWORD GroupType
Definition: shared.h:414
SOCKADDR WSRemoteAddress
Definition: shared.h:424
BOOLEAN UseSAN
Definition: shared.h:408
DWORD ProviderFlags
Definition: shared.h:412
DWORD dwServiceFlags3
Definition: winsock2.h:676
DWORD dwCatalogEntryId
Definition: winsock2.h:680
DWORD dwServiceFlags4
Definition: winsock2.h:677
DWORD dwServiceFlags1
Definition: winsock2.h:674
DWORD dwProviderFlags
Definition: winsock2.h:678
LPWPUMODIFYIFSHANDLE lpWPUModifyIFSHandle
Definition: ws2spi.h:608
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define WSA_FLAG_MULTIPOINT_D_LEAF
Definition: winsock2.h:464
#define XP1_MULTIPOINT_DATA_PLANE
Definition: winsock2.h:442
#define WSA_FLAG_MULTIPOINT_C_ROOT
Definition: winsock2.h:461
#define XP1_SUPPORT_MULTIPOINT
Definition: winsock2.h:440
#define XP1_PSEUDO_STREAM
Definition: winsock2.h:434
#define XP1_MULTIPOINT_CONTROL_PLANE
Definition: winsock2.h:441
#define XP1_MESSAGE_ORIENTED
Definition: winsock2.h:433
#define WSA_FLAG_MULTIPOINT_D_ROOT
Definition: winsock2.h:463
#define WSA_FLAG_MULTIPOINT_C_LEAF
Definition: winsock2.h:462
#define SOCK_RAW
Definition: winsock.h:331
#define AF_UNSPEC
Definition: winsock.h:338
_In_ USHORT SocketType
Definition: wsk.h:182

Referenced by WSPAccept(), and WSPStartup().

◆ WSPStartup()

_Must_inspect_result_ int WSPAPI WSPStartup ( _In_ WORD  wVersionRequested,
_In_ LPWSPDATA  lpWSPData,
_In_ LPWSAPROTOCOL_INFOW  lpProtocolInfo,
_In_ WSPUPCALLTABLE  UpcallTable,
_Out_ LPWSPPROC_TABLE  lpProcTable 
)

Definition at line 3431 of file dllmain.c.

3437{
3439
3440 if (((LOBYTE(wVersionRequested) == 2) && (HIBYTE(wVersionRequested) < 2)) ||
3441 (LOBYTE(wVersionRequested) < 2))
3442 {
3443 ERR("WSPStartup NOT SUPPORTED for version 0x%X\n", wVersionRequested);
3444 return WSAVERNOTSUPPORTED;
3445 }
3446 else
3447 Status = NO_ERROR;
3448 /* FIXME: Enable all cases of WSPStartup status */
3449 Upcalls = UpcallTable;
3450
3451 if (Status == NO_ERROR)
3452 {
3453 lpProcTable->lpWSPAccept = WSPAccept;
3454 lpProcTable->lpWSPAddressToString = WSPAddressToString;
3455 lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect;
3456 lpProcTable->lpWSPBind = WSPBind;
3457 lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall;
3458 lpProcTable->lpWSPCleanup = WSPCleanup;
3459 lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
3460 lpProcTable->lpWSPConnect = WSPConnect;
3461 lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket;
3462 lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents;
3463 lpProcTable->lpWSPEventSelect = WSPEventSelect;
3464 lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult;
3465 lpProcTable->lpWSPGetPeerName = WSPGetPeerName;
3466 lpProcTable->lpWSPGetSockName = WSPGetSockName;
3467 lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt;
3468 lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName;
3469 lpProcTable->lpWSPIoctl = WSPIoctl;
3470 lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf;
3471 lpProcTable->lpWSPListen = WSPListen;
3472 lpProcTable->lpWSPRecv = WSPRecv;
3473 lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect;
3474 lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
3475 lpProcTable->lpWSPSelect = WSPSelect;
3476 lpProcTable->lpWSPSend = WSPSend;
3477 lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect;
3478 lpProcTable->lpWSPSendTo = WSPSendTo;
3479 lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt;
3480 lpProcTable->lpWSPShutdown = WSPShutdown;
3481 lpProcTable->lpWSPSocket = WSPSocket;
3482 lpProcTable->lpWSPStringToAddress = WSPStringToAddress;
3483 lpWSPData->wVersion = MAKEWORD(2, 2);
3484 lpWSPData->wHighVersion = MAKEWORD(2, 2);
3485 /* Save CatalogEntryId for all upcalls */
3486 CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
3487 }
3488
3489 TRACE("Status (%d).\n", Status);
3490 return Status;
3491}
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:3496
int WSPAPI WSPListen(SOCKET Handle, int Backlog, LPINT lpErrno)
Definition: dllmain.c:998
INT WSPAPI WSPSetSockOpt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen, OUT LPINT lpErrno)
Definition: dllmain.c:3214
INT WSPAPI WSPCleanup(OUT LPINT lpErrno)
Definition: dllmain.c:3680
int WSPAPI WSPConnect(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
Definition: dllmain.c:2017
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:2925
DWORD CatalogEntryId
Definition: dllmain.c:21
INT WSPAPI WSPGetPeerName(IN SOCKET s, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
Definition: dllmain.c:2579
INT WSPAPI WSPDuplicateSocket(IN SOCKET Handle, IN DWORD dwProcessId, OUT LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPINT lpErrno)
Definition: dllmain.c:449
int WSPAPI WSPShutdown(SOCKET Handle, int HowTo, LPINT lpErrno)
Definition: dllmain.c:2397
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:3556
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:2682
_Must_inspect_result_ SOCKET WSPAPI WSPAccept(_In_ SOCKET Handle, _Out_writes_bytes_to_opt_(*addrlen, *addrlen) struct sockaddr FAR *SocketAddress, _Inout_opt_ LPINT SocketAddressLength, _In_opt_ LPCONDITIONPROC lpfnCondition, _In_opt_ DWORD_PTR dwCallbackData, _Out_ LPINT lpErrno)
Definition: dllmain.c:1451
INT WSPAPI WSPGetSockName(IN SOCKET Handle, OUT LPSOCKADDR Name, IN OUT LPINT NameLength, OUT LPINT lpErrno)
Definition: dllmain.c:2477
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
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
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
INT WSPAPI WSPSendDisconnect(IN SOCKET s, IN LPWSABUF lpOutboundDisconnectData, OUT LPINT lpErrno)
Definition: sndrcv.c:1064
int WSPAPI WSPRecvFrom(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRead, LPDWORD ReceiveFlags, struct sockaddr *SocketAddress, int *SocketAddressLength, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:430
BOOL WSPAPI WSPGetOverlappedResult(IN SOCKET Handle, IN LPWSAOVERLAPPED lpOverlapped, OUT LPDWORD lpdwBytes, IN BOOL fWait, OUT LPDWORD lpdwFlags, OUT LPINT lpErrno)
Definition: sndrcv.c:96
INT WSPAPI WSPAsyncSelect(IN SOCKET Handle, IN HWND hWnd, IN UINT wMsg, IN LONG lEvent, OUT LPINT lpErrno)
Definition: sndrcv.c:17
int WSPAPI WSPSendTo(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD iFlags, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:843
int WSPAPI WSPSend(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD iFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:668
int WSPAPI WSPRecv(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRead, LPDWORD ReceiveFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:221
INT WSPAPI WSPRecvDisconnect(IN SOCKET s, OUT LPWSABUF lpInboundDisconnectData, OUT LPINT lpErrno)
Definition: sndrcv.c:1052
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#define WSAVERNOTSUPPORTED
Definition: winerror.h:2893

◆ WSPStringToAddress()

INT WSPAPI WSPStringToAddress ( IN LPWSTR  AddressString,
IN INT  AddressFamily,
IN LPWSAPROTOCOL_INFOW  lpProtocolInfo,
OUT LPSOCKADDR  lpAddress,
IN OUT LPINT  lpAddressLength,
OUT LPINT  lpErrno 
)

Definition at line 3556 of file dllmain.c.

3562{
3563 int numdots = 0;
3564 USHORT port;
3565 LONG inetaddr = 0, ip_part;
3566 LPWSTR *bp = NULL;
3568
3569 if (!lpAddressLength || !lpAddress || !AddressString)
3570 {
3571 if (lpErrno) *lpErrno = WSAEINVAL;
3572 return SOCKET_ERROR;
3573 }
3574
3575 sockaddr = (SOCKADDR_IN *)lpAddress;
3576
3577 /* Set right address family */
3578 if (lpProtocolInfo != NULL)
3579 {
3580 sockaddr->sin_family = lpProtocolInfo->iAddressFamily;
3581 }
3582 else
3583 {
3584 sockaddr->sin_family = AddressFamily;
3585 }
3586
3587 /* Report size */
3588 if (AddressFamily == AF_INET)
3589 {
3590 if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN))
3591 {
3592 if (lpErrno) *lpErrno = WSAEFAULT;
3593 }
3594 else
3595 {
3596 // translate ip string to ip
3597
3598 /* Get ip number */
3599 bp = &AddressString;
3600 inetaddr = 0;
3601
3602 while (*bp < &AddressString[wcslen(AddressString)])
3603 {
3604 ip_part = wcstol(*bp, bp, 10);
3605 /* ip part number should be in range 0-255 */
3606 if (ip_part < 0 || ip_part > 255)
3607 {
3608 if (lpErrno) *lpErrno = WSAEINVAL;
3609 return SOCKET_ERROR;
3610 }
3611 inetaddr = (inetaddr << 8) + ip_part;
3612 /* we end on string end or port separator */
3613 if ((*bp)[0] == 0 || (*bp)[0] == L':')
3614 break;
3615 /* ip parts are dot separated. verify it */
3616 if ((*bp)[0] != L'.')
3617 {
3618 if (lpErrno) *lpErrno = WSAEINVAL;
3619 return SOCKET_ERROR;
3620 }
3621 /* count the dots */
3622 numdots++;
3623 /* move over the dot to next ip part */
3624 (*bp)++;
3625 }
3626
3627 /* check dots count */
3628 if (numdots != 3)
3629 {
3630 if (lpErrno) *lpErrno = WSAEINVAL;
3631 return SOCKET_ERROR;
3632 }
3633
3634 /* Get port number */
3635 if ((*bp)[0] == L':')
3636 {
3637 /* move over the column to port part */
3638 (*bp)++;
3639 /* next char should be numeric */
3640 if ((*bp)[0] < L'0' || (*bp)[0] > L'9')
3641 {
3642 if (lpErrno) *lpErrno = WSAEINVAL;
3643 return SOCKET_ERROR;
3644 }
3645 port = wcstol(*bp, bp, 10);
3646 }
3647 else
3648 {
3649 port = 0;
3650 }
3651
3652 if (lpErrno) *lpErrno = NO_ERROR;
3653 /* rest sockaddr.sin_addr.s_addr
3654 for we need to be sure it is zero when we come to while */
3655 *lpAddressLength = sizeof(*sockaddr);
3656 memset(lpAddress, 0, sizeof(*sockaddr));
3657 sockaddr->sin_family = AF_INET;
3658 sockaddr->sin_addr.s_addr = inetaddr;
3659 sockaddr->sin_port = port;
3660 }
3661 }
3662
3663 if (lpErrno && !*lpErrno)
3664 {
3665 return 0;
3666 }
3667
3668 return SOCKET_ERROR;
3669}
_ACRTIMP __msvcrt_long __cdecl wcstol(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2752
USHORT port
Definition: uri.c:210
#define memset(x, y, z)
Definition: compat.h:39
uint16_t * LPWSTR
Definition: typedefs.h:56
struct sockaddr_in SOCKADDR_IN
Definition: winsock.h:481

Referenced by WSPStartup().

Variable Documentation

◆ CatalogEntryId

◆ GlobalHeap

◆ lpWPUCompleteOverlappedRequest

LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest

Definition at line 22 of file dllmain.c.

◆ SockAsyncCompletionPort

◆ SockAsyncHelperAfdHandle

HANDLE SockAsyncHelperAfdHandle

Definition at line 27 of file dllmain.c.

Referenced by SockGetAsyncSelectHelperAfdHandle(), and SockProcessAsyncSelect().

◆ SockAsyncSelectCalled

BOOLEAN SockAsyncSelectCalled

Definition at line 29 of file dllmain.c.

Referenced by SockGetAsyncSelectHelperAfdHandle().

◆ SockAsyncThreadRefCount

ULONG SockAsyncThreadRefCount

Definition at line 26 of file dllmain.c.

Referenced by SockCreateOrReferenceAsyncThread().

◆ SocketListHead

PSOCKET_INFORMATION SocketListHead = NULL

Definition at line 23 of file dllmain.c.

Referenced by GetSocketStructure(), WSPCloseSocket(), and WSPSocket().

◆ SocketListLock

CRITICAL_SECTION SocketListLock

Definition at line 24 of file dllmain.c.

Referenced by DllMain(), GetSocketStructure(), WSPCloseSocket(), and WSPSocket().

◆ SockHelpersListHead

LIST_ENTRY SockHelpersListHead = { NULL, NULL }

Definition at line 25 of file dllmain.c.

Referenced by DllMain(), SockGetTdiName(), and SockLoadHelperDll().

◆ Upcalls

WSPUPCALLTABLE Upcalls

Definition at line 20 of file dllmain.c.

Referenced by SockAsyncSelectCompletionRoutine(), WSPSocket(), and WSPStartup().