ReactOS 0.4.15-dev-5874-gc762234
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)
 
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)
 
int WSPAPI WSPConnect (SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
 
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)
 
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)
 
VOID NTAPI AfdInfoAPC (PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, 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

◆ AfdInfoAPC()

VOID NTAPI AfdInfoAPC ( PVOID  ApcContext,
PIO_STATUS_BLOCK  IoStatusBlock,
ULONG  Reserved 
)

Definition at line 3255 of file dllmain.c.

3258{
3260
3261 Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
3263}
#define HeapFree(x, y, z)
Definition: compat.h:735
HANDLE GlobalHeap
Definition: dllmain.c:19
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:727

Referenced by GetSocketInformation(), and SetSocketInformation().

◆ CreateContext()

int CreateContext ( PSOCKET_INFORMATION  Socket)

Definition at line 3539 of file dllmain.c.

3540{
3541 IO_STATUS_BLOCK IOSB;
3542 SOCKET_CONTEXT ContextData;
3545
3548 NULL,
3550 FALSE);
3551
3552 if( !NT_SUCCESS(Status) )
3553 return SOCKET_ERROR;
3554
3555 /* Create Context */
3556 ContextData.SharedData = *Socket->SharedData;
3557 ContextData.SizeOfHelperData = 0;
3558 RtlCopyMemory (&ContextData.LocalAddress,
3559 Socket->LocalAddress,
3561 RtlCopyMemory (&ContextData.RemoteAddress,
3562 Socket->RemoteAddress,
3564
3565 /* Send IOCTL */
3567 SockEvent,
3568 NULL,
3569 NULL,
3570 &IOSB,
3572 &ContextData,
3573 sizeof(ContextData),
3574 NULL,
3575 0);
3576
3577 /* Wait for Completion */
3578 if (Status == STATUS_PENDING)
3579 {
3581 Status = IOSB.Status;
3582 }
3583
3584 NtClose( SockEvent );
3585
3587}
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:32
HANDLE SockEvent
#define INFINITE
Definition: serial.h:102
Status
Definition: gdiplustypes.h:25
#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:3402
@ 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 STATUS_PENDING
Definition: ntstatus.h:82
#define IOCTL_AFD_SET_CONTEXT
Definition: shared.h:301
#define STATUS_SUCCESS
Definition: shellext.h:65
SOCK_SHARED_INFO SharedData
Definition: msafd.h:121
SOCKADDR RemoteAddress
Definition: msafd.h:125
SOCKADDR LocalAddress
Definition: msafd.h:124
ULONG SizeOfHelperData
Definition: msafd.h:122
PSOCKADDR LocalAddress
Definition: msafd.h:105
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:100
PSOCKADDR RemoteAddress
Definition: msafd.h:106
SOCKET Handle
Definition: msafd.h:99
INT SizeOfLocalAddress
Definition: msafd.h:59
INT SizeOfRemoteAddress
Definition: msafd.h:60
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define SOCKET_ERROR
Definition: winsock.h:333

Referenced by WSPSocket().

◆ DllMain()

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

Definition at line 4039 of file dllmain.c.

4042{
4043
4044 switch (dwReason)
4045 {
4046 case DLL_PROCESS_ATTACH:
4047
4048 TRACE("Loading MSAFD.DLL \n");
4049
4050 /* Don't need thread attach notifications
4051 so disable them to improve performance */
4052 DisableThreadLibraryCalls(hInstDll);
4053
4054 /* List of DLL Helpers */
4056
4057 /* Heap to use when allocating */
4059
4060 /* Initialize the lock that protects our socket list */
4062
4063 TRACE("MSAFD.DLL has been loaded\n");
4064
4065 break;
4066
4067 case DLL_THREAD_ATTACH:
4068 break;
4069
4070 case DLL_THREAD_DETACH:
4071 break;
4072
4073 case DLL_PROCESS_DETACH:
4074
4075 /* Delete the socket list lock */
4077
4078 break;
4079 }
4080
4081 TRACE("DllMain of msafd.dll (leaving)\n");
4082
4083 return TRUE;
4084}
DWORD dwReason
Definition: misc.cpp:154
#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
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:751
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

◆ GetCurrentTimeInSeconds()

DWORD GetCurrentTimeInSeconds ( VOID  )

Definition at line 1417 of file dllmain.c.

1418{
1419 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
1420 union
1421 {
1422 FILETIME ft;
1423 ULONGLONG ll;
1424 } u1970, Time;
1425
1427 SystemTimeToFileTime(&st1970, &u1970.ft);
1428 return (DWORD)((Time.ll - u1970.ll) / 10000000ULL);
1429}
w ll
Definition: byte_order.h:166
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
unsigned long DWORD
Definition: ntddk_ex.h:95
static PLARGE_INTEGER Time
Definition: time.c:105
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by 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 3266 of file dllmain.c.

3273{
3274 PIO_STATUS_BLOCK IOSB;
3275 IO_STATUS_BLOCK DummyIOSB;
3276 AFD_INFO InfoData;
3278 PAFDAPCCONTEXT APCContext;
3279 PIO_APC_ROUTINE APCFunction;
3280 HANDLE Event = NULL;
3282
3285 NULL,
3287 FALSE);
3288
3289 if( !NT_SUCCESS(Status) )
3290 return SOCKET_ERROR;
3291
3292 /* Set Info Class */
3293 InfoData.InformationClass = AfdInformationClass;
3294
3295 /* Verify if we should use APC */
3296 if (Overlapped == NULL)
3297 {
3298 /* Not using Overlapped structure, so use normal blocking on event */
3299 APCContext = NULL;
3300 APCFunction = NULL;
3301 Event = SockEvent;
3302 IOSB = &DummyIOSB;
3303 }
3304 else
3305 {
3306 /* Overlapped request for non overlapped opened socket */
3307 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3308 {
3309 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3310 NtClose( SockEvent );
3311 return 0;
3312 }
3313 if (CompletionRoutine == NULL)
3314 {
3315 /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
3316 APCContext = (PAFDAPCCONTEXT)Overlapped;
3317 APCFunction = NULL;
3318 Event = Overlapped->hEvent;
3319 }
3320 else
3321 {
3322 /* Using Overlapped Structure and a Completition Routine, so use an APC */
3323 APCFunction = &AfdInfoAPC; // should be a private io completition function inside us
3324 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
3325 if (!APCContext)
3326 {
3327 ERR("Not enough memory for APC Context\n");
3328 NtClose( SockEvent );
3329 return WSAEFAULT;
3330 }
3332 APCContext->lpOverlapped = Overlapped;
3333 APCContext->lpSocket = Socket;
3334 }
3335
3336 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3337 }
3338
3339 IOSB->Status = STATUS_PENDING;
3340
3341 /* Send IOCTL */
3343 Event,
3344 APCFunction,
3345 APCContext,
3346 IOSB,
3348 &InfoData,
3349 sizeof(InfoData),
3350 &InfoData,
3351 sizeof(InfoData));
3352
3353 /* Wait for return */
3354 if (Status == STATUS_PENDING && Overlapped == NULL)
3355 {
3357 Status = IOSB->Status;
3358 }
3359
3360 NtClose( SockEvent );
3361
3362 TRACE("Status %x Information %d\n", Status, IOSB->Information);
3363
3364 if (Status == STATUS_PENDING)
3365 {
3366 TRACE("Leaving (Pending)\n");
3367 return WSA_IO_PENDING;
3368 }
3369
3370 if (Status != STATUS_SUCCESS)
3371 return SOCKET_ERROR;
3372
3373 /* Return Information */
3374 if (Ulong != NULL)
3375 {
3376 *Ulong = InfoData.Information.Ulong;
3377 }
3378 if (LargeInteger != NULL)
3379 {
3380 *LargeInteger = InfoData.Information.LargeInteger;
3381 }
3382 if (Boolean != NULL)
3383 {
3384 *Boolean = InfoData.Information.Boolean;
3385 }
3386
3387 return NO_ERROR;
3388
3389}
#define ERR(fmt,...)
Definition: debug.h:110
#define HeapAlloc
Definition: compat.h:733
VOID NTAPI AfdInfoAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
Definition: dllmain.c:3255
struct _AFDAPCCONTEXT * PAFDAPCCONTEXT
#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:877
#define IOCTL_AFD_GET_INFO
Definition: shared.h:327
PSOCKET_INFORMATION lpSocket
Definition: msafd.h:140
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
Definition: msafd.h:139
LPWSAOVERLAPPED lpOverlapped
Definition: msafd.h:138
ULONG InformationClass
Definition: shared.h:29
union _AFD_INFO::@3349 Information
ULONG Ulong
Definition: shared.h:31
BOOLEAN Boolean
Definition: shared.h:33
LARGE_INTEGER LargeInteger
Definition: shared.h:32
DWORD CreateFlags
Definition: msafd.h:81
unsigned long Ulong
Definition: utypes.h:42
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
#define WSAEFAULT
Definition: winerror.h:1945
#define WSA_IO_PENDING
Definition: winsock2.h:616

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

◆ GetSocketStructure()

PSOCKET_INFORMATION GetSocketStructure ( SOCKET  Handle)

Definition at line 3516 of file dllmain.c.

3517{
3518 PSOCKET_INFORMATION CurrentSocket;
3519
3521
3522 CurrentSocket = SocketListHead;
3523 while (CurrentSocket)
3524 {
3525 if (CurrentSocket->Handle == Handle)
3526 {
3528 return CurrentSocket;
3529 }
3530
3531 CurrentSocket = CurrentSocket->NextSocket;
3532 }
3533
3535
3536 return NULL;
3537}
PSOCKET_INFORMATION SocketListHead
Definition: dllmain.c:23
ULONG Handle
Definition: gdb_input.c:15
struct _SOCKET_INFORMATION * NextSocket
Definition: msafd.h:116
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by WSPAccept(), WSPAsyncSelect(), WSPBind(), WSPCloseSocket(), WSPConnect(), WSPDuplicateSocket(), WSPEnumNetworkEvents(), WSPEventSelect(), WSPGetOverlappedResult(), WSPGetPeerName(), WSPGetSockName(), WSPGetSockOpt(), WSPIoctl(), WSPListen(), WSPRecv(), WSPRecvFrom(), WSPSelect(), WSPSend(), WSPSendTo(), WSPSetSockOpt(), 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 3393 of file dllmain.c.

3400{
3401 PIO_STATUS_BLOCK IOSB;
3402 IO_STATUS_BLOCK DummyIOSB;
3403 AFD_INFO InfoData;
3405 PAFDAPCCONTEXT APCContext;
3406 PIO_APC_ROUTINE APCFunction;
3407 HANDLE Event = NULL;
3409
3412 NULL,
3414 FALSE);
3415
3416 if( !NT_SUCCESS(Status) )
3417 return SOCKET_ERROR;
3418
3419 /* Set Info Class */
3420 InfoData.InformationClass = AfdInformationClass;
3421
3422 /* Set Information */
3423 if (Ulong != NULL)
3424 {
3425 InfoData.Information.Ulong = *Ulong;
3426 }
3427 if (LargeInteger != NULL)
3428 {
3429 InfoData.Information.LargeInteger = *LargeInteger;
3430 }
3431 if (Boolean != NULL)
3432 {
3433 InfoData.Information.Boolean = *Boolean;
3434 }
3435
3436 /* Verify if we should use APC */
3437 if (Overlapped == NULL)
3438 {
3439 /* Not using Overlapped structure, so use normal blocking on event */
3440 APCContext = NULL;
3441 APCFunction = NULL;
3442 Event = SockEvent;
3443 IOSB = &DummyIOSB;
3444 }
3445 else
3446 {
3447 /* Overlapped request for non overlapped opened socket */
3448 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
3449 {
3450 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
3451 NtClose( SockEvent );
3452 return 0;
3453 }
3454 if (CompletionRoutine == NULL)
3455 {
3456 /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
3457 APCContext = (PAFDAPCCONTEXT)Overlapped;
3458 APCFunction = NULL;
3459 Event = Overlapped->hEvent;
3460 }
3461 else
3462 {
3463 /* Using Overlapped Structure and a Completition Routine, so use an APC */
3464 APCFunction = &AfdInfoAPC; // should be a private io completition function inside us
3465 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
3466 if (!APCContext)
3467 {
3468 ERR("Not enough memory for APC Context\n");
3469 NtClose( SockEvent );
3470 return WSAEFAULT;
3471 }
3473 APCContext->lpOverlapped = Overlapped;
3474 APCContext->lpSocket = Socket;
3475 }
3476
3477 IOSB = (PIO_STATUS_BLOCK)&Overlapped->Internal;
3478 }
3479
3480 IOSB->Status = STATUS_PENDING;
3481
3482 /* Send IOCTL */
3484 Event,
3485 APCFunction,
3486 APCContext,
3487 IOSB,
3489 &InfoData,
3490 sizeof(InfoData),
3491 NULL,
3492 0);
3493
3494 /* Wait for return */
3495 if (Status == STATUS_PENDING && Overlapped == NULL)
3496 {
3498 Status = IOSB->Status;
3499 }
3500
3501 NtClose( SockEvent );
3502
3503 TRACE("Status %x Information %d\n", Status, IOSB->Information);
3504
3505 if (Status == STATUS_PENDING)
3506 {
3507 TRACE("Leaving (Pending)\n");
3508 return WSA_IO_PENDING;
3509 }
3510
3512
3513}
#define IOCTL_AFD_SET_INFO
Definition: shared.h:295

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

◆ SockAsyncSelectCompletionRoutine()

VOID SockAsyncSelectCompletionRoutine ( PVOID  Context,
PIO_STATUS_BLOCK  IoStatusBlock 
)

Definition at line 3746 of file dllmain.c.

3747{
3748
3749 PASYNC_DATA AsyncData = Context;
3750 PSOCKET_INFORMATION Socket;
3751 ULONG x;
3752
3753 /* Get the Socket */
3754 Socket = AsyncData->ParentSocket;
3755
3756 /* Check if the Sequence Number Changed behind our back */
3757 if (AsyncData->SequenceNumber != Socket->SharedData->SequenceNumber )
3758 {
3759 return;
3760 }
3761
3762 /* Check we were manually called b/c of a failure */
3764 {
3765 /* FIXME: Perform Upcall */
3766 return;
3767 }
3768
3769 for (x = 1; x; x<<=1)
3770 {
3771 switch (AsyncData->AsyncSelectInfo.Handles[0].Events & x)
3772 {
3773 case AFD_EVENT_RECEIVE:
3774 if (0 != (Socket->SharedData->AsyncEvents & FD_READ) &&
3775 0 == (Socket->SharedData->AsyncDisabledEvents & FD_READ))
3776 {
3777 /* Make the Notification */
3779 Socket->SharedData->wMsg,
3780 Socket->Handle,
3782 /* Disable this event until the next read(); */
3784 }
3785 break;
3786
3788 if (0 != (Socket->SharedData->AsyncEvents & FD_OOB) &&
3789 0 == (Socket->SharedData->AsyncDisabledEvents & FD_OOB))
3790 {
3791 /* Make the Notification */
3793 Socket->SharedData->wMsg,
3794 Socket->Handle,
3796 /* Disable this event until the next read(); */
3798 }
3799 break;
3800
3801 case AFD_EVENT_SEND:
3802 if (0 != (Socket->SharedData->AsyncEvents & FD_WRITE) &&
3803 0 == (Socket->SharedData->AsyncDisabledEvents & FD_WRITE))
3804 {
3805 /* Make the Notification */
3807 Socket->SharedData->wMsg,
3808 Socket->Handle,
3810 /* Disable this event until the next write(); */
3812 }
3813 break;
3814
3815 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
3816 case AFD_EVENT_CONNECT:
3818 if (0 != (Socket->SharedData->AsyncEvents & FD_CONNECT) &&
3819 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CONNECT))
3820 {
3821 /* Make the Notification */
3823 Socket->SharedData->wMsg,
3824 Socket->Handle,
3826 /* Disable this event forever; */
3828 }
3829 break;
3830
3831 case AFD_EVENT_ACCEPT:
3832 if (0 != (Socket->SharedData->AsyncEvents & FD_ACCEPT) &&
3833 0 == (Socket->SharedData->AsyncDisabledEvents & FD_ACCEPT))
3834 {
3835 /* Make the Notification */
3837 Socket->SharedData->wMsg,
3838 Socket->Handle,
3840 /* Disable this event until the next accept(); */
3842 }
3843 break;
3844
3846 case AFD_EVENT_ABORT:
3847 case AFD_EVENT_CLOSE:
3848 if (0 != (Socket->SharedData->AsyncEvents & FD_CLOSE) &&
3849 0 == (Socket->SharedData->AsyncDisabledEvents & FD_CLOSE))
3850 {
3851 /* Make the Notification */
3853 Socket->SharedData->wMsg,
3854 Socket->Handle,
3856 /* Disable this event forever; */
3858 }
3859 break;
3860 /* FIXME: Support QOS */
3861 }
3862 }
3863
3864 /* Check if there are any events left for us to check */
3865 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
3866 {
3867 return;
3868 }
3869
3870 /* Keep Polling */
3871 SockProcessAsyncSelect(Socket, AsyncData);
3872 return;
3873}
VOID SockProcessAsyncSelect(PSOCKET_INFORMATION Socket, PASYNC_DATA AsyncData)
Definition: dllmain.c:3875
WSPUPCALLTABLE Upcalls
Definition: dllmain.c:20
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define AFD_EVENT_ACCEPT
Definition: shared.h:210
#define AFD_EVENT_SEND
Definition: shared.h:205
#define AFD_EVENT_OOB_RECEIVE
Definition: shared.h:204
#define AFD_EVENT_CONNECT_FAIL
Definition: shared.h:211
#define AFD_EVENT_RECEIVE
Definition: shared.h:203
#define AFD_EVENT_DISCONNECT
Definition: shared.h:206
#define AFD_EVENT_ABORT
Definition: shared.h:207
#define AFD_EVENT_CLOSE
Definition: shared.h:208
#define AFD_EVENT_CONNECT
Definition: shared.h:209
ULONG Events
Definition: shared.h:51
AFD_HANDLE Handles[1]
Definition: shared.h:59
AFD_POLL_INFO AsyncSelectInfo
Definition: msafd.h:133
DWORD SequenceNumber
Definition: msafd.h:131
PSOCKET_INFORMATION ParentSocket
Definition: msafd.h:130
LONG AsyncDisabledEvents
Definition: msafd.h:93
LONG AsyncEvents
Definition: msafd.h:92
DWORD SequenceNumber
Definition: msafd.h:90
LPWPUPOSTMESSAGE lpWPUPostMessage
Definition: ws2spi.h:609
uint32_t ULONG
Definition: typedefs.h:59
#define FD_READ
Definition: winsock.h:405
#define FD_WRITE
Definition: winsock.h:406
#define FD_CLOSE
Definition: winsock.h:410
#define FD_CONNECT
Definition: winsock.h:409
#define WSAMAKESELECTREPLY(e, error)
Definition: winsock.h:478
#define FD_OOB
Definition: winsock.h:407
#define FD_ACCEPT
Definition: winsock.h:408

Referenced by SockGetAsyncSelectHelperAfdHandle(), and SockProcessAsyncSelect().

◆ SockAsyncThread()

ULONG NTAPI SockAsyncThread ( PVOID  ThreadParam)

Definition at line 3650 of file dllmain.c.

3651{
3652 PVOID AsyncContext;
3653 PASYNC_COMPLETION_ROUTINE AsyncCompletionRoutine;
3654 IO_STATUS_BLOCK IOSB;
3656
3657 /* Make the Thread Higher Priority */
3659
3660 /* Do a KQUEUE/WorkItem Style Loop, thanks to IoCompletion Ports */
3661 do
3662 {
3664 (PVOID*)&AsyncCompletionRoutine,
3665 &AsyncContext,
3666 &IOSB,
3667 NULL);
3668 /* Call the Async Function */
3669 if (NT_SUCCESS(Status))
3670 {
3671 (*AsyncCompletionRoutine)(AsyncContext, &IOSB);
3672 }
3673 else
3674 {
3675 /* It Failed, sleep for a second */
3676 Sleep(1000);
3677 }
3678 } while ((Status != STATUS_TIMEOUT));
3679
3680 /* The Thread has Ended */
3681 return 0;
3682}
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
HANDLE SockAsyncCompletionPort
Definition: dllmain.c:28
VOID(* PASYNC_COMPLETION_ROUTINE)(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: msafd.h:542
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
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
#define THREAD_PRIORITY_ABOVE_NORMAL
Definition: winbase.h:275

Referenced by SockCreateOrReferenceAsyncThread().

◆ SockCreateOrReferenceAsyncThread()

BOOLEAN SockCreateOrReferenceAsyncThread ( VOID  )

Definition at line 3589 of file dllmain.c.

3590{
3591 HANDLE hAsyncThread;
3592 DWORD AsyncThreadId;
3593 HANDLE AsyncEvent;
3596
3597 /* Check if the Thread Already Exists */
3599 {
3601 return TRUE;
3602 }
3603
3604 /* Create the Completion Port */
3606 {
3609 NULL,
3610 2); // Allow 2 threads only
3611 if (!NT_SUCCESS(Status))
3612 {
3613 ERR("Failed to create completion port: 0x%08x\n", Status);
3614 return FALSE;
3615 }
3616 /* Protect Handle */
3617 HandleFlags.ProtectFromClose = TRUE;
3618 HandleFlags.Inherit = FALSE;
3620 ObjectHandleFlagInformation,
3621 &HandleFlags,
3622 sizeof(HandleFlags));
3623 }
3624
3625 /* Create the Async Event */
3626 Status = NtCreateEvent(&AsyncEvent,
3628 NULL,
3630 FALSE);
3631
3632 /* Create the Async Thread */
3633 hAsyncThread = CreateThread(NULL,
3634 0,
3636 NULL,
3637 0,
3638 &AsyncThreadId);
3639
3640 /* Close the Handle */
3641 NtClose(hAsyncThread);
3642
3643 /* Increase the Reference Count */
3645 return TRUE;
3646}
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:3650
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:72
@ NotificationEvent
NTSTATUS NTAPI NtSetInformationObject(IN HANDLE ObjectHandle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, IN PVOID ObjectInformation, IN ULONG Length)
Definition: oblife.c:1809

Referenced by SockReenableAsyncSelectEvent(), and WSPAsyncSelect().

◆ SockGetAsyncSelectHelperAfdHandle()

BOOLEAN SockGetAsyncSelectHelperAfdHandle ( VOID  )

Definition at line 3684 of file dllmain.c.

3685{
3686 UNICODE_STRING AfdHelper;
3688 IO_STATUS_BLOCK IoSb;
3689 FILE_COMPLETION_INFORMATION CompletionInfo;
3691
3692 /* First, make sure we're not already initialized */
3694 {
3695 return TRUE;
3696 }
3697
3698 /* Set up Handle Name and Object */
3699 RtlInitUnicodeString(&AfdHelper, L"\\Device\\Afd\\AsyncSelectHlp" );
3701 &AfdHelper,
3703 NULL,
3704 NULL);
3705
3706 /* Open the Handle to AFD */
3710 &IoSb,
3711 NULL,
3712 0,
3715 0,
3716 NULL,
3717 0);
3718
3719 /*
3720 * Now Set up the Completion Port Information
3721 * This means that whenever a Poll is finished, the routine will be executed
3722 */
3723 CompletionInfo.Port = SockAsyncCompletionPort;
3724 CompletionInfo.Key = SockAsyncSelectCompletionRoutine;
3726 &IoSb,
3727 &CompletionInfo,
3728 sizeof(CompletionInfo),
3730
3731
3732 /* Protect the Handle */
3733 HandleFlags.ProtectFromClose = TRUE;
3734 HandleFlags.Inherit = FALSE;
3736 ObjectHandleFlagInformation,
3737 &HandleFlags,
3738 sizeof(HandleFlags));
3739
3740
3741 /* Set this variable to true so that Send/Recv/Accept will know wether to renable disabled events */
3743 return TRUE;
3744}
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:3746
HANDLE SockAsyncHelperAfdHandle
Definition: dllmain.c:27
BOOLEAN SockAsyncSelectCalled
Definition: dllmain.c:29
@ FileCompletionInformation
Definition: from_kernel.h:91
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#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 L(x)
Definition: ntvdm.h:50

Referenced by WSPAsyncSelect().

◆ SockProcessAsyncSelect()

VOID SockProcessAsyncSelect ( PSOCKET_INFORMATION  Socket,
PASYNC_DATA  AsyncData 
)

Definition at line 3875 of file dllmain.c.

3876{
3877
3878 ULONG lNetworkEvents;
3880
3881 /* Set up the Async Data Event Info */
3882 AsyncData->AsyncSelectInfo.Timeout.HighPart = 0x7FFFFFFF;
3883 AsyncData->AsyncSelectInfo.Timeout.LowPart = 0xFFFFFFFF;
3884 AsyncData->AsyncSelectInfo.HandleCount = 1;
3885 AsyncData->AsyncSelectInfo.Exclusive = TRUE;
3886 AsyncData->AsyncSelectInfo.Handles[0].Handle = Socket->Handle;
3887 AsyncData->AsyncSelectInfo.Handles[0].Events = 0;
3888
3889 /* Remove unwanted events */
3890 lNetworkEvents = Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents);
3891
3892 /* Set Events to wait for */
3893 if (lNetworkEvents & FD_READ)
3894 {
3896 }
3897
3898 if (lNetworkEvents & FD_WRITE)
3899 {
3901 }
3902
3903 if (lNetworkEvents & FD_OOB)
3904 {
3906 }
3907
3908 if (lNetworkEvents & FD_ACCEPT)
3909 {
3911 }
3912
3913 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
3914 if (lNetworkEvents & FD_CONNECT)
3915 {
3917 }
3918
3919 if (lNetworkEvents & FD_CLOSE)
3920 {
3922 }
3923
3924 if (lNetworkEvents & FD_QOS)
3925 {
3927 }
3928
3929 if (lNetworkEvents & FD_GROUP_QOS)
3930 {
3932 }
3933
3934 /* Send IOCTL */
3936 NULL,
3937 NULL,
3938 AsyncData,
3939 &AsyncData->IoStatusBlock,
3941 &AsyncData->AsyncSelectInfo,
3942 sizeof(AsyncData->AsyncSelectInfo),
3943 &AsyncData->AsyncSelectInfo,
3944 sizeof(AsyncData->AsyncSelectInfo));
3945
3946 /* I/O Manager Won't call the completion routine, let's do it manually */
3947 if (NT_SUCCESS(Status))
3948 {
3949 return;
3950 }
3951 else
3952 {
3953 AsyncData->IoStatusBlock.Status = Status;
3954 SockAsyncSelectCompletionRoutine(AsyncData, &AsyncData->IoStatusBlock);
3955 }
3956}
#define IOCTL_AFD_SELECT
Definition: shared.h:285
#define AFD_EVENT_QOS
Definition: shared.h:212
#define AFD_EVENT_GROUP_QOS
Definition: shared.h:213
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:132
ULONG LowPart
Definition: typedefs.h:106
#define FD_QOS
Definition: winsock2.h:306
#define FD_GROUP_QOS
Definition: winsock2.h:308

Referenced by SockAsyncSelectCompletionRoutine(), and SockProcessQueuedAsyncSelect().

◆ SockProcessQueuedAsyncSelect()

VOID SockProcessQueuedAsyncSelect ( PVOID  Context,
PIO_STATUS_BLOCK  IoStatusBlock 
)

Definition at line 3958 of file dllmain.c.

3959{
3960 PASYNC_DATA AsyncData = Context;
3961 BOOL FreeContext = TRUE;
3962 PSOCKET_INFORMATION Socket;
3963
3964 /* Get the Socket */
3965 Socket = AsyncData->ParentSocket;
3966
3967 /* If someone closed it, stop the function */
3968 if (Socket->SharedData->State != SocketClosed)
3969 {
3970 /* Check if the Sequence Number changed by now, in which case quit */
3971 if (AsyncData->SequenceNumber == Socket->SharedData->SequenceNumber)
3972 {
3973 /* Do the actual select, if needed */
3974 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)))
3975 {
3976 SockProcessAsyncSelect(Socket, AsyncData);
3977 FreeContext = FALSE;
3978 }
3979 }
3980 }
3981
3982 /* Free the Context */
3983 if (FreeContext)
3984 {
3985 HeapFree(GetProcessHeap(), 0, AsyncData);
3986 }
3987
3988 return;
3989}
@ SocketClosed
Definition: msafd.h:50
unsigned int BOOL
Definition: ntddk_ex.h:94
SOCKET_STATE State
Definition: msafd.h:54

Referenced by SockReenableAsyncSelectEvent(), and WSPAsyncSelect().

◆ SockReenableAsyncSelectEvent()

VOID SockReenableAsyncSelectEvent ( IN PSOCKET_INFORMATION  Socket,
IN ULONG  Event 
)

Definition at line 3992 of file dllmain.c.

3994{
3995 PASYNC_DATA AsyncData;
3996
3997 /* Make sure the event is actually disabled */
3998 if (!(Socket->SharedData->AsyncDisabledEvents & Event))
3999 {
4000 return;
4001 }
4002
4003 /* Re-enable it */
4004 Socket->SharedData->AsyncDisabledEvents &= ~Event;
4005
4006 /* Return if no more events are being polled */
4007 if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0 )
4008 {
4009 return;
4010 }
4011
4012 /* Wait on new events */
4013 AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(ASYNC_DATA));
4014 if (!AsyncData) return;
4015
4016 /* Create the Asynch Thread if Needed */
4018
4019 /* Increase the sequence number to stop anything else */
4020 Socket->SharedData->SequenceNumber++;
4021
4022 /* Set up the Async Data */
4023 AsyncData->ParentSocket = Socket;
4024 AsyncData->SequenceNumber = Socket->SharedData->SequenceNumber;
4025
4026 /* Begin Async Select by using I/O Completion */
4029 AsyncData,
4030 0,
4031 0);
4032
4033 /* All done */
4034 return;
4035}
BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
Definition: dllmain.c:3589
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:3958
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
Definition: iocomp.c:569

Referenced by AfdAPC(), 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_INVALID_ADDRESS
Definition: ntstatus.h:557
#define STATUS_NETWORK_UNREACHABLE
Definition: ntstatus.h:704
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define STATUS_ADDRESS_ALREADY_EXISTS
Definition: ntstatus.h:654
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
#define STATUS_HOST_UNREACHABLE
Definition: ntstatus.h:705
#define STATUS_REMOTE_DISCONNECT
Definition: ntstatus.h:552
#define STATUS_INVALID_CONNECTION
Definition: ntstatus.h:556
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_REMOTE_NOT_LISTENING
Definition: ntstatus.h:424
#define STATUS_LOCAL_DISCONNECT
Definition: ntstatus.h:551
#define STATUS_PROTOCOL_NOT_SUPPORTED
Definition: ntstatus.h:1177
#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_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define WSAEADDRNOTAVAIL
Definition: winerror.h:1962
#define WSAEOPNOTSUPP
Definition: winerror.h:1958
#define WSAEHOSTUNREACH
Definition: winerror.h:1978
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define WSAEINVAL
Definition: winerror.h:1946
#define WSAECONNABORTED
Definition: winerror.h:1966
#define WSAENETDOWN
Definition: winerror.h:1963
#define WSAENOBUFS
Definition: winerror.h:1968
#define WSAETIMEDOUT
Definition: winerror.h:1973
#define WSAEMSGSIZE
Definition: winerror.h:1953
#define WSAECONNRESET
Definition: winerror.h:1967
#define WSAEACCES
Definition: winerror.h:1944
#define WSAESHUTDOWN
Definition: winerror.h:1971
#define WSAENETUNREACH
Definition: winerror.h:1964
#define WSAEAFNOSUPPORT
Definition: winerror.h:1960
#define WSAECONNREFUSED
Definition: winerror.h:1974
#define WSAENOTCONN
Definition: winerror.h:1970
#define WSAEADDRINUSE
Definition: winerror.h:1961
#define WSA_OPERATION_ABORTED
Definition: winsock2.h:621

Referenced by MsafdReturnWithErrno(), WSPAccept(), WSPBind(), WSPConnect(), WSPEnumNetworkEvents(), 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 1434 of file dllmain.c.

1441{
1442 IO_STATUS_BLOCK IOSB;
1443 PAFD_RECEIVED_ACCEPT_DATA ListenReceiveData;
1444 AFD_ACCEPT_DATA AcceptData;
1445 AFD_DEFER_ACCEPT_DATA DeferData;
1446 AFD_PENDING_ACCEPT_DATA PendingAcceptData;
1447 PSOCKET_INFORMATION Socket = NULL;
1449 struct fd_set ReadSet;
1450 struct timeval Timeout;
1451 PVOID PendingData = NULL;
1452 ULONG PendingDataLength = 0;
1453 PVOID CalleeDataBuffer;
1454 WSABUF CallerData, CalleeID, CallerID, CalleeData;
1456 GROUP GroupID = 0;
1457 ULONG CallBack;
1459 PSOCKET_INFORMATION AcceptSocketInfo;
1460 UCHAR ReceiveBuffer[0x1A];
1462
1463 /* Get the Socket Structure associate to this Socket*/
1464 Socket = GetSocketStructure(Handle);
1465 if (!Socket)
1466 {
1467 if (lpErrno) *lpErrno = WSAENOTSOCK;
1468 return SOCKET_ERROR;
1469 }
1470 if (!Socket->SharedData->Listening)
1471 {
1472 if (lpErrno) *lpErrno = WSAEINVAL;
1473 return SOCKET_ERROR;
1474 }
1475 if ((SocketAddress && !SocketAddressLength) ||
1476 (SocketAddressLength && !SocketAddress) ||
1477 (SocketAddressLength && *SocketAddressLength < sizeof(SOCKADDR)))
1478 {
1479 if (lpErrno) *lpErrno = WSAEFAULT;
1480 return INVALID_SOCKET;
1481 }
1482
1485 NULL,
1487 FALSE);
1488
1489 if( !NT_SUCCESS(Status) )
1490 {
1491 return SOCKET_ERROR;
1492 }
1493
1494 /* Dynamic Structure...ugh */
1495 ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
1496
1497 /* If this is non-blocking, make sure there's something for us to accept */
1498 FD_ZERO(&ReadSet);
1499 FD_SET(Socket->Handle, &ReadSet);
1500 Timeout.tv_sec=0;
1501 Timeout.tv_usec=0;
1502
1503 if (WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, lpErrno) == SOCKET_ERROR)
1504 {
1506 return SOCKET_ERROR;
1507 }
1508
1509 if (ReadSet.fd_array[0] != Socket->Handle)
1510 {
1512 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
1513 return SOCKET_ERROR;
1514 }
1515
1516 /* Send IOCTL */
1518 SockEvent,
1519 NULL,
1520 NULL,
1521 &IOSB,
1523 NULL,
1524 0,
1525 ListenReceiveData,
1526 0xA + sizeof(*ListenReceiveData));
1527
1528 /* Wait for return */
1529 if (Status == STATUS_PENDING)
1530 {
1532 Status = IOSB.Status;
1533 }
1534
1535 if (!NT_SUCCESS(Status))
1536 {
1537 NtClose( SockEvent );
1538 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1539 }
1540
1541 if (lpfnCondition != NULL)
1542 {
1543 if ((Socket->SharedData->ServiceFlags1 & XP1_CONNECT_DATA) != 0)
1544 {
1545 /* Find out how much data is pending */
1546 PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1547 PendingAcceptData.ReturnSize = TRUE;
1548
1549 /* Send IOCTL */
1551 SockEvent,
1552 NULL,
1553 NULL,
1554 &IOSB,
1556 &PendingAcceptData,
1557 sizeof(PendingAcceptData),
1558 &PendingAcceptData,
1559 sizeof(PendingAcceptData));
1560
1561 /* Wait for return */
1562 if (Status == STATUS_PENDING)
1563 {
1565 Status = IOSB.Status;
1566 }
1567
1568 if (!NT_SUCCESS(Status))
1569 {
1570 NtClose( SockEvent );
1571 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1572 }
1573
1574 /* How much data to allocate */
1575 PendingDataLength = IOSB.Information;
1576
1577 if (PendingDataLength)
1578 {
1579 /* Allocate needed space */
1580 PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength);
1581 if (!PendingData)
1582 {
1584 }
1585
1586 /* We want the data now */
1587 PendingAcceptData.ReturnSize = FALSE;
1588
1589 /* Send IOCTL */
1591 SockEvent,
1592 NULL,
1593 NULL,
1594 &IOSB,
1596 &PendingAcceptData,
1597 sizeof(PendingAcceptData),
1598 PendingData,
1599 PendingDataLength);
1600
1601 /* Wait for return */
1602 if (Status == STATUS_PENDING)
1603 {
1605 Status = IOSB.Status;
1606 }
1607
1608 if (!NT_SUCCESS(Status))
1609 {
1610 NtClose( SockEvent );
1611 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1612 }
1613 }
1614 }
1615
1616 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1617 {
1618 /* I don't support this yet */
1619 }
1620
1621 /* Build Callee ID */
1622 CalleeID.buf = (PVOID)Socket->LocalAddress;
1623 CalleeID.len = Socket->SharedData->SizeOfLocalAddress;
1624
1626 if (!RemoteAddress)
1627 {
1629 }
1630
1631 /* Set up Address in SOCKADDR Format */
1633 &ListenReceiveData->Address.Address[0].AddressType,
1634 sizeof(*RemoteAddress));
1635
1636 /* Build Caller ID */
1637 CallerID.buf = (PVOID)RemoteAddress;
1638 CallerID.len = sizeof(*RemoteAddress);
1639
1640 /* Build Caller Data */
1641 CallerData.buf = PendingData;
1642 CallerData.len = PendingDataLength;
1643
1644 /* Check if socket supports Conditional Accept */
1645 if (Socket->SharedData->UseDelayedAcceptance != 0)
1646 {
1647 /* Allocate Buffer for Callee Data */
1648 CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096);
1649 if (!CalleeDataBuffer) {
1651 }
1652 CalleeData.buf = CalleeDataBuffer;
1653 CalleeData.len = 4096;
1654 }
1655 else
1656 {
1657 /* Nothing */
1658 CalleeData.buf = 0;
1659 CalleeData.len = 0;
1660 }
1661
1662 /* Call the Condition Function */
1663 CallBack = (lpfnCondition)(&CallerID,
1664 CallerData.buf == NULL ? NULL : &CallerData,
1665 NULL,
1666 NULL,
1667 &CalleeID,
1668 CalleeData.buf == NULL ? NULL : &CalleeData,
1669 &GroupID,
1670 dwCallbackData);
1671
1672 if (((CallBack == CF_ACCEPT) && GroupID) != 0)
1673 {
1674 /* TBD: Check for Validity */
1675 }
1676
1677 if (CallBack == CF_ACCEPT)
1678 {
1679 if ((Socket->SharedData->ServiceFlags1 & XP1_QOS_SUPPORTED) != 0)
1680 {
1681 /* I don't support this yet */
1682 }
1683 if (CalleeData.buf)
1684 {
1685 // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0
1686 }
1687 }
1688 else
1689 {
1690 /* Callback rejected. Build Defer Structure */
1691 DeferData.SequenceNumber = ListenReceiveData->SequenceNumber;
1692 DeferData.RejectConnection = (CallBack == CF_REJECT);
1693
1694 /* Send IOCTL */
1696 SockEvent,
1697 NULL,
1698 NULL,
1699 &IOSB,
1701 &DeferData,
1702 sizeof(DeferData),
1703 NULL,
1704 0);
1705
1706 /* Wait for return */
1707 if (Status == STATUS_PENDING)
1708 {
1710 Status = IOSB.Status;
1711 }
1712
1713 NtClose( SockEvent );
1714
1715 if (!NT_SUCCESS(Status))
1716 {
1717 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1718 }
1719
1720 if (CallBack == CF_REJECT )
1721 {
1722 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1723 return SOCKET_ERROR;
1724 }
1725 else
1726 {
1727 if (lpErrno) *lpErrno = WSAECONNREFUSED;
1728 return SOCKET_ERROR;
1729 }
1730 }
1731 }
1732
1733 /* Create a new Socket */
1735 Socket->SharedData->SocketType,
1736 Socket->SharedData->Protocol,
1737 &Socket->ProtocolInfo,
1738 GroupID,
1739 Socket->SharedData->CreateFlags,
1740 lpErrno);
1742 return SOCKET_ERROR;
1743
1744 /* Set up the Accept Structure */
1745 AcceptData.ListenHandle = (HANDLE)AcceptSocket;
1746 AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
1747
1748 /* Send IOCTL to Accept */
1750 SockEvent,
1751 NULL,
1752 NULL,
1753 &IOSB,
1755 &AcceptData,
1756 sizeof(AcceptData),
1757 NULL,
1758 0);
1759
1760 /* Wait for return */
1761 if (Status == STATUS_PENDING)
1762 {
1764 Status = IOSB.Status;
1765 }
1766
1768 if (!NT_SUCCESS(Status))
1769 {
1771 WSPCloseSocket( AcceptSocket, lpErrno );
1772 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
1773 }
1774
1775 AcceptSocketInfo = GetSocketStructure(AcceptSocket);
1776 if (!AcceptSocketInfo)
1777 {
1779 WSPCloseSocket( AcceptSocket, lpErrno );
1781 }
1782
1783 AcceptSocketInfo->SharedData->State = SocketConnected;
1784 AcceptSocketInfo->SharedData->ConnectTime = GetCurrentTimeInSeconds();
1785
1786 /* Return Address in SOCKADDR FORMAT */
1787 if( SocketAddress )
1788 {
1789 RtlCopyMemory (SocketAddress,
1790 &ListenReceiveData->Address.Address[0].AddressType,
1791 sizeof(*RemoteAddress));
1792 if( SocketAddressLength )
1793 *SocketAddressLength = sizeof(*RemoteAddress);
1794 }
1795
1796 NtClose( SockEvent );
1797
1798 /* Re-enable Async Event */
1800
1801 TRACE("Socket %x\n", AcceptSocket);
1802
1804 {
1805 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1806 Socket->Handle,
1807 Socket->TdiAddressHandle,
1808 Socket->TdiConnectionHandle,
1810
1811 if (Status)
1812 {
1813 if (lpErrno) *lpErrno = Status;
1814 return SOCKET_ERROR;
1815 }
1816 }
1817
1818 if (lpErrno) *lpErrno = NO_ERROR;
1819
1820 /* Return Socket */
1821 return AcceptSocket;
1822}
DWORD GetCurrentTimeInSeconds(VOID)
Definition: dllmain.c:1417
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3516
int WSPAPI WSPSelect(IN int nfds, IN OUT fd_set *readfds OPTIONAL, IN OUT fd_set *writefds OPTIONAL, IN OUT fd_set *exceptfds OPTIONAL, IN const struct timeval *timeout OPTIONAL, OUT LPINT lpErrno)
Definition: dllmain.c:1065
INT WSPAPI WSPCloseSocket(IN SOCKET Handle, OUT LPINT lpErrno)
Definition: dllmain.c:623
INT TranslateNtStatusError(NTSTATUS Status)
Definition: dllmain.c:537
SOCKET WSPAPI WSPSocket(int AddressFamily, int SocketType, int Protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)
Definition: dllmain.c:48
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3992
FORCEINLINE DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes)
Definition: msafd.h:546
@ SocketConnected
Definition: msafd.h:49
static ULONG Timeout
Definition: ping.c:61
#define IOCTL_AFD_WAIT_FOR_LISTEN
Definition: shared.h:273
#define IOCTL_AFD_DEFER_ACCEPT
Definition: shared.h:331
struct _AFD_RECEIVED_ACCEPT_DATA * PAFD_RECEIVED_ACCEPT_DATA
#define IOCTL_AFD_ACCEPT
Definition: shared.h:275
#define IOCTL_AFD_GET_PENDING_CONNECT_DATA
Definition: shared.h:333
HANDLE ListenHandle
Definition: shared.h:65
ULONG SequenceNumber
Definition: shared.h:64
BOOLEAN RejectConnection
Definition: shared.h:81
TRANSPORT_ADDRESS Address
Definition: shared.h:70
PWSH_NOTIFY WSHNotify
Definition: helpers.h:25
PVOID HelperContext
Definition: msafd.h:104
HANDLE TdiConnectionHandle
Definition: msafd.h:108
PHELPER_DATA HelperData
Definition: msafd.h:103
HANDLE TdiAddressHandle
Definition: msafd.h:107
DWORD HelperEvents
Definition: msafd.h:102
WSAPROTOCOL_INFOW ProtocolInfo
Definition: msafd.h:115
INT AddressFamily
Definition: msafd.h:56
INT SocketLastError
Definition: msafd.h:87
INT SocketType
Definition: msafd.h:57
BOOLEAN Listening
Definition: msafd.h:68
BOOLEAN UseDelayedAcceptance
Definition: msafd.h:78
DWORD ServiceFlags1
Definition: msafd.h:82
ULONG ConnectTime
Definition: msafd.h:66
USHORT AddressType
Definition: tdi.h:339
TA_ADDRESS Address[1]
Definition: tdi.h:377
ULONG len
Definition: ws2def.h:519
CHAR FAR * buf
Definition: ws2def.h:520
Definition: winsock.h:66
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
#define WSAENOTSOCK
Definition: winerror.h:1951
unsigned int GROUP
Definition: winsock2.h:640
#define CF_REJECT
Definition: winsock2.h:414
#define XP1_QOS_SUPPORTED
Definition: winsock2.h:449
#define CF_ACCEPT
Definition: winsock2.h:413
#define XP1_CONNECT_DATA
Definition: winsock2.h:443
#define FD_ZERO(set)
Definition: winsock.h:96
#define INVALID_SOCKET
Definition: winsock.h:332
UINT_PTR SOCKET
Definition: winsock.h:47
#define FD_SET(fd, set)
Definition: winsock.h:89
#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
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by WSPStartup().

◆ 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 3059 of file dllmain.c.

3065{
3066 SIZE_T size;
3067 WCHAR buffer[54]; /* 32 digits + 7':' + '[' + '%" + 5 digits + ']:' + 5 digits + '\0' */
3068 WCHAR *p;
3069
3070 if (!lpsaAddress || !lpszAddressString || !lpdwAddressStringLength)
3071 {
3072 if (lpErrno) *lpErrno = WSAEFAULT;
3073 return SOCKET_ERROR;
3074 }
3075
3076 switch (lpsaAddress->sa_family)
3077 {
3078 case AF_INET:
3079 if (dwAddressLength < sizeof(SOCKADDR_IN))
3080 {
3081 if (lpErrno) *lpErrno = WSAEINVAL;
3082 return SOCKET_ERROR;
3083 }
3085 L"%u.%u.%u.%u:%u",
3086 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 24 & 0xff),
3087 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 16 & 0xff),
3088 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) >> 8 & 0xff),
3089 (unsigned int)(ntohl(((SOCKADDR_IN *)lpsaAddress)->sin_addr.s_addr) & 0xff),
3090 ntohs(((SOCKADDR_IN *)lpsaAddress)->sin_port));
3091
3092 p = wcschr(buffer, L':');
3093 if (!((SOCKADDR_IN *)lpsaAddress)->sin_port)
3094 {
3095 *p = 0;
3096 }
3097 break;
3098 default:
3099 if (lpErrno) *lpErrno = WSAEINVAL;
3100 return SOCKET_ERROR;
3101 }
3102
3103 size = wcslen(buffer) + 1;
3104
3105 if (*lpdwAddressStringLength < size)
3106 {
3107 *lpdwAddressStringLength = size;
3108 if (lpErrno) *lpErrno = WSAEFAULT;
3109 return SOCKET_ERROR;
3110 }
3111
3112 *lpdwAddressStringLength = size;
3113 wcscpy(lpszAddressString, buffer);
3114 return 0;
3115}
#define wcschr
Definition: compat.h:17
#define swprintf
Definition: precomp.h:40
#define AF_INET
Definition: tcpip.h:117
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLfloat GLfloat p
Definition: glext.h:8902
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ntohl(x)
Definition: module.h:203
#define ntohs(x)
Definition: module.h:208
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by WSPStartup().

◆ WSPBind()

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

Definition at line 846 of file dllmain.c.

850{
851 IO_STATUS_BLOCK IOSB;
852 PAFD_BIND_DATA BindData;
853 PSOCKET_INFORMATION Socket = NULL;
855 SOCKADDR_INFO SocketInfo;
857
858 /* Get the Socket Structure associate to this Socket*/
859 Socket = GetSocketStructure(Handle);
860 if (!Socket)
861 {
862 if (lpErrno) *lpErrno = WSAENOTSOCK;
863 return SOCKET_ERROR;
864 }
865 if (Socket->SharedData->State != SocketOpen)
866 {
867 if (lpErrno) *lpErrno = WSAEINVAL;
868 return SOCKET_ERROR;
869 }
870 if (!SocketAddress || SocketAddressLength < Socket->SharedData->SizeOfLocalAddress)
871 {
872 if (lpErrno) *lpErrno = WSAEINVAL;
873 return SOCKET_ERROR;
874 }
875
876 /* Get Address Information */
877 Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
878 SocketAddressLength,
879 &SocketInfo);
880
881 if (SocketInfo.AddressInfo == SockaddrAddressInfoBroadcast && !Socket->SharedData->Broadcast)
882 {
883 if (lpErrno) *lpErrno = WSAEADDRNOTAVAIL;
884 return SOCKET_ERROR;
885 }
886
889 NULL,
891 FALSE);
892
893 if (!NT_SUCCESS(Status))
894 {
895 return SOCKET_ERROR;
896 }
897
898 /* See below */
899 BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength);
900 if (!BindData)
901 {
903 }
904
905 /* Set up Address in TDI Format */
906 BindData->Address.TAAddressCount = 1;
907 BindData->Address.Address[0].AddressLength = (USHORT)(SocketAddressLength - sizeof(SocketAddress->sa_family));
908 BindData->Address.Address[0].AddressType = SocketAddress->sa_family;
909 RtlCopyMemory (BindData->Address.Address[0].Address,
910 SocketAddress->sa_data,
911 SocketAddressLength - sizeof(SocketAddress->sa_family));
912
913 /* Set the Share Type */
914 if (Socket->SharedData->ExclusiveAddressUse)
915 {
916 BindData->ShareType = AFD_SHARE_EXCLUSIVE;
917 }
918 else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard)
919 {
920 BindData->ShareType = AFD_SHARE_WILDCARD;
921 }
922 else if (Socket->SharedData->ReuseAddresses)
923 {
924 BindData->ShareType = AFD_SHARE_REUSE;
925 }
926 else
927 {
928 BindData->ShareType = AFD_SHARE_UNIQUE;
929 }
930
931 /* Send IOCTL */
933 SockEvent,
934 NULL,
935 NULL,
936 &IOSB,
938 BindData,
939 0xA + Socket->SharedData->SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
940 BindData,
941 0xA + Socket->SharedData->SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
942
943 /* Wait for return */
944 if (Status == STATUS_PENDING)
945 {
947 Status = IOSB.Status;
948 }
949
951 HeapFree(GlobalHeap, 0, BindData);
952
954 if (Status != STATUS_SUCCESS)
955 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
956
957 /* Set up Socket Data */
958 Socket->SharedData->State = SocketBound;
959 Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
960
962 {
963 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
964 Socket->Handle,
965 Socket->TdiAddressHandle,
966 Socket->TdiConnectionHandle,
968
969 if (Status)
970 {
971 if (lpErrno) *lpErrno = Status;
972 return SOCKET_ERROR;
973 }
974 }
975
976 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
977}
@ SocketBound
Definition: msafd.h:47
@ SocketOpen
Definition: msafd.h:46
if(dx< 0)
Definition: linetemp.h:194
unsigned short USHORT
Definition: pedump.c:61
#define AFD_SHARE_WILDCARD
Definition: shared.h:193
#define IOCTL_AFD_BIND
Definition: shared.h:267
#define AFD_SHARE_UNIQUE
Definition: shared.h:191
#define AFD_SHARE_EXCLUSIVE
Definition: shared.h:194
#define AFD_SHARE_REUSE
Definition: shared.h:192
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: msafd.h:69
BOOLEAN ExclusiveAddressUse
Definition: msafd.h:73
BOOLEAN ReuseAddresses
Definition: msafd.h:72
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:217
char sa_data[14]
Definition: winsock.h:218
@ 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 3243 of file dllmain.c.

3245{
3246 TRACE("Leaving.\n");
3247
3248 if (lpErrno) *lpErrno = NO_ERROR;
3249
3250 return 0;
3251}

Referenced by WSPStartup(), and WsTpWSPCleanup().

◆ WSPCloseSocket()

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

Definition at line 623 of file dllmain.c.

625{
627 PSOCKET_INFORMATION Socket = NULL, CurrentSocket;
630 AFD_DISCONNECT_INFO DisconnectInfo;
631 SOCKET_STATE OldState;
632 LONG LingerWait = -1;
633 DWORD References;
634
635 /* Get the Socket Structure associate to this Socket*/
636 Socket = GetSocketStructure(Handle);
637 if (!Socket)
638 {
639 if (lpErrno) *lpErrno = WSAENOTSOCK;
640 return SOCKET_ERROR;
641 }
642
643 /* Create the Wait Event */
646 NULL,
648 FALSE);
649
650 if(!NT_SUCCESS(Status))
651 {
652 ERR("NtCreateEvent failed: 0x%08x\n", Status);
653 return SOCKET_ERROR;
654 }
655
656 if (Socket->HelperEvents & WSH_NOTIFY_CLOSE)
657 {
658 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
659 Socket->Handle,
660 Socket->TdiAddressHandle,
661 Socket->TdiConnectionHandle,
663
664 if (Status)
665 {
666 if (lpErrno) *lpErrno = Status;
667 ERR("WSHNotify failed. Error 0x%#x\n", Status);
669 return SOCKET_ERROR;
670 }
671 }
672
673 /* If a Close is already in Process, give up */
674 if (Socket->SharedData->State == SocketClosed)
675 {
676 WARN("Socket is closing.\n");
678 if (lpErrno) *lpErrno = WSAENOTSOCK;
679 return SOCKET_ERROR;
680 }
681
682 /* Decrement reference count on SharedData */
683 References = InterlockedDecrement(&Socket->SharedData->RefCount);
684 if (References)
685 goto ok;
686
687 /* Set the state to close */
688 OldState = Socket->SharedData->State;
689 Socket->SharedData->State = SocketClosed;
690
691 /* If SO_LINGER is ON and the Socket is connected, we need to disconnect */
692 /* FIXME: Should we do this on Datagram Sockets too? */
693 if ((OldState == SocketConnected) && (Socket->SharedData->LingerData.l_onoff))
694 {
695 ULONG SendsInProgress;
696 ULONG SleepWait;
697
698 /* We need to respect the timeout */
699 SleepWait = 100;
700 LingerWait = Socket->SharedData->LingerData.l_linger * 1000;
701
702 /* Loop until no more sends are pending, within the timeout */
703 while (LingerWait)
704 {
705 /* Find out how many Sends are in Progress */
706 if (GetSocketInformation(Socket,
708 NULL,
709 &SendsInProgress,
710 NULL,
711 NULL,
712 NULL))
713 {
714 /* Bail out if anything but NO_ERROR */
715 LingerWait = 0;
716 break;
717 }
718
719 /* Bail out if no more sends are pending */
720 if (!SendsInProgress)
721 {
722 LingerWait = -1;
723 break;
724 }
725
726 /*
727 * We have to execute a sleep, so it's kind of like
728 * a block. If the socket is Nonblock, we cannot
729 * go on since asynchronous operation is expected
730 * and we cannot offer it
731 */
732 if (Socket->SharedData->NonBlocking)
733 {
734 WARN("Would block!\n");
736 Socket->SharedData->State = OldState;
737 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
738 return SOCKET_ERROR;
739 }
740
741 /* Now we can sleep, and decrement the linger wait */
742 /*
743 * FIXME: It seems Windows does some funky acceleration
744 * since the waiting seems to be longer and longer. I
745 * don't think this improves performance so much, so we
746 * wait a fixed time instead.
747 */
748 Sleep(SleepWait);
749 LingerWait -= SleepWait;
750 }
751 }
752
753 if (OldState == SocketConnected)
754 {
755 if (LingerWait <= 0)
756 {
757 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(0);
758 DisconnectInfo.DisconnectType = LingerWait < 0 ? AFD_DISCONNECT_SEND : AFD_DISCONNECT_ABORT;
759
760 if (((DisconnectInfo.DisconnectType & AFD_DISCONNECT_SEND) && (!Socket->SharedData->SendShutdown)) ||
761 ((DisconnectInfo.DisconnectType & AFD_DISCONNECT_ABORT) && (!Socket->SharedData->ReceiveShutdown)))
762 {
763 /* Send IOCTL */
765 SockEvent,
766 NULL,
767 NULL,
770 &DisconnectInfo,
771 sizeof(DisconnectInfo),
772 NULL,
773 0);
774
775 /* Wait for return */
776 if (Status == STATUS_PENDING)
777 {
780 }
781 }
782 }
783 }
784
785 /* Cleanup Time! */
786 Socket->HelperContext = NULL;
787 Socket->SharedData->AsyncDisabledEvents = -1;
788 NtClose(Socket->TdiAddressHandle);
789 Socket->TdiAddressHandle = NULL;
791 Socket->TdiConnectionHandle = NULL;
792ok:
794 if (SocketListHead == Socket)
795 {
797 }
798 else
799 {
800 CurrentSocket = SocketListHead;
801 while (CurrentSocket->NextSocket)
802 {
803 if (CurrentSocket->NextSocket == Socket)
804 {
805 CurrentSocket->NextSocket = CurrentSocket->NextSocket->NextSocket;
806 break;
807 }
808
809 CurrentSocket = CurrentSocket->NextSocket;
810 }
811 }
813
814 /* Close the handle */
817
819 {
820 /* It is a duplicated socket, so unmap the memory */
822 NtClose(Socket->SharedDataHandle);
823 Socket->SharedData = NULL;
824 }
825 if( !References && Socket->SharedData )
826 {
827 HeapFree(GlobalHeap, 0, Socket->SharedData);
828 }
829 HeapFree(GlobalHeap, 0, Socket);
830 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
831}
#define InterlockedDecrement
Definition: armddk.h:52
#define ok(value,...)
Definition: atltest.h:57
#define WARN(fmt,...)
Definition: debug.h:112
#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:3266
enum _SOCKET_STATE SOCKET_STATE
NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG)
Definition: largeint.c:31
long LONG
Definition: pedump.c:60
#define AFD_DISCONNECT_ABORT
Definition: shared.h:199
#define IOCTL_AFD_DISCONNECT
Definition: shared.h:287
#define AFD_INFO_SENDS_IN_PROGRESS
Definition: shared.h:184
#define AFD_DISCONNECT_SEND
Definition: shared.h:197
LARGE_INTEGER Timeout
Definition: shared.h:137
ULONG DisconnectType
Definition: shared.h:136
HANDLE SharedDataHandle
Definition: msafd.h:101
BOOLEAN NonBlocking
Definition: msafd.h:74
BOOLEAN SendShutdown
Definition: msafd.h:77
LONG RefCount
Definition: msafd.h:55
struct linger LingerData
Definition: msafd.h:61
BOOLEAN ReceiveShutdown
Definition: msafd.h:76
#define WSH_NOTIFY_CLOSE
Definition: wsahelp.h:17

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 1826 of file dllmain.c.

1834{
1835 IO_STATUS_BLOCK IOSB;
1836 PAFD_CONNECT_INFO ConnectInfo = NULL;
1837 PSOCKET_INFORMATION Socket;
1839 INT Errno;
1840 ULONG ConnectDataLength;
1841 ULONG InConnectDataLength;
1842 INT BindAddressLength;
1843 PSOCKADDR BindAddress;
1845 int SocketDataLength;
1846
1847 TRACE("Called (%lx) %lx:%d\n", Handle, ((const struct sockaddr_in *)SocketAddress)->sin_addr, ((const struct sockaddr_in *)SocketAddress)->sin_port);
1848
1849 /* Get the Socket Structure associate to this Socket*/
1850 Socket = GetSocketStructure(Handle);
1851 if (!Socket)
1852 {
1853 if (lpErrno) *lpErrno = WSAENOTSOCK;
1854 return SOCKET_ERROR;
1855 }
1856
1859 NULL,
1861 FALSE);
1862
1863 if (!NT_SUCCESS(Status))
1864 return SOCKET_ERROR;
1865
1866 /* Bind us First */
1867 if (Socket->SharedData->State == SocketOpen)
1868 {
1869 /* Get the Wildcard Address */
1870 BindAddressLength = Socket->HelperData->MaxWSAddressLength;
1871 BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength);
1872 if (!BindAddress)
1873 {
1876 }
1878 BindAddress,
1879 &BindAddressLength);
1880 /* Bind it */
1881 if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR)
1882 return SOCKET_ERROR;
1883 }
1884
1885 /* Set the Connect Data */
1886 if (lpCallerData != NULL)
1887 {
1888 ConnectDataLength = lpCallerData->len;
1890 SockEvent,
1891 NULL,
1892 NULL,
1893 &IOSB,
1895 lpCallerData->buf,
1896 ConnectDataLength,
1897 NULL,
1898 0);
1899 /* Wait for return */
1900 if (Status == STATUS_PENDING)
1901 {
1903 Status = IOSB.Status;
1904 }
1905
1906 if (Status != STATUS_SUCCESS)
1907 goto notify;
1908 }
1909
1910 /* Calculate the size of SocketAddress->sa_data */
1911 SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
1912
1913 /* Allocate a connection info buffer with SocketDataLength bytes of payload */
1914 ConnectInfo = HeapAlloc(GetProcessHeap(), 0,
1916 RemoteAddress.Address[0].Address[SocketDataLength]));
1917 if (!ConnectInfo)
1918 {
1920 goto notify;
1921 }
1922
1923 /* Set up Address in TDI Format */
1924 ConnectInfo->RemoteAddress.TAAddressCount = 1;
1925 ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
1926 ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
1928 SocketAddress->sa_data,
1929 SocketDataLength);
1930
1931 /*
1932 * Disable FD_WRITE and FD_CONNECT
1933 * The latter fixes a race condition where the FD_CONNECT is re-enabled
1934 * at the end of this function right after the Async Thread disables it.
1935 * This should only happen at the *next* WSPConnect
1936 */
1937 if (Socket->SharedData->AsyncEvents & FD_CONNECT)
1938 {
1940 }
1941
1942 /* Tell AFD that we want Connection Data back, have it allocate a buffer */
1943 if (lpCalleeData != NULL)
1944 {
1945 InConnectDataLength = lpCalleeData->len;
1947 SockEvent,
1948 NULL,
1949 NULL,
1950 &IOSB,
1952 &InConnectDataLength,
1953 sizeof(InConnectDataLength),
1954 NULL,
1955 0);
1956
1957 /* Wait for return */
1958 if (Status == STATUS_PENDING)
1959 {
1961 Status = IOSB.Status;
1962 }
1963
1964 if (Status != STATUS_SUCCESS)
1965 goto notify;
1966 }
1967
1968 /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */
1969 ConnectInfo->Root = 0;
1970 ConnectInfo->UseSAN = FALSE;
1971 ConnectInfo->Unknown = 0;
1972
1973 /* FIXME: Handle Async Connect */
1974 if (Socket->SharedData->NonBlocking)
1975 {
1976 ERR("Async Connect UNIMPLEMENTED!\n");
1977 }
1978
1979 /* Send IOCTL */
1981 SockEvent,
1982 NULL,
1983 NULL,
1984 &IOSB,
1986 ConnectInfo,
1987 0x22,
1988 NULL,
1989 0);
1990 /* Wait for return */
1991 if (Status == STATUS_PENDING)
1992 {
1994 Status = IOSB.Status;
1995 }
1996
1998 if (Status != STATUS_SUCCESS)
1999 goto notify;
2000
2001 Socket->SharedData->State = SocketConnected;
2002 Socket->TdiConnectionHandle = (HANDLE)IOSB.Information;
2004
2005 /* Get any pending connect data */
2006 if (lpCalleeData != NULL)
2007 {
2009 SockEvent,
2010 NULL,
2011 NULL,
2012 &IOSB,
2014 NULL,
2015 0,
2016 lpCalleeData->buf,
2017 lpCalleeData->len);
2018 /* Wait for return */
2019 if (Status == STATUS_PENDING)
2020 {
2022 Status = IOSB.Status;
2023 }
2024 }
2025
2026 TRACE("Ending %lx\n", IOSB.Status);
2027
2028notify:
2029 if (ConnectInfo) HeapFree(GetProcessHeap(), 0, ConnectInfo);
2030
2031 /* Re-enable Async Event */
2033
2034 /* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
2036
2038
2040 {
2041 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2042 Socket->Handle,
2043 Socket->TdiAddressHandle,
2044 Socket->TdiConnectionHandle,
2046
2047 if (Errno)
2048 {
2049 if (lpErrno) *lpErrno = Errno;
2050 return SOCKET_ERROR;
2051 }
2052 }
2054 {
2055 Errno = Socket->HelperData->WSHNotify(Socket->HelperContext,
2056 Socket->Handle,
2057 Socket->TdiAddressHandle,
2058 Socket->TdiConnectionHandle,
2060
2061 if (Errno)
2062 {
2063 if (lpErrno) *lpErrno = Errno;
2064 return SOCKET_ERROR;
2065 }
2066 }
2067
2068 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
2069}
INT WSPAPI WSPBind(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPINT lpErrno)
Definition: dllmain.c:846
int notify
Definition: msacm.c:1366
#define IOCTL_AFD_SET_CONNECT_DATA
Definition: shared.h:303
#define IOCTL_AFD_CONNECT
Definition: shared.h:269
#define IOCTL_AFD_SET_CONNECT_DATA_SIZE
Definition: shared.h:319
#define IOCTL_AFD_GET_CONNECT_DATA
Definition: shared.h:311
TRANSPORT_ADDRESS RemoteAddress
Definition: shared.h:121
BOOLEAN UseSAN
Definition: shared.h:118
INT MaxWSAddressLength
Definition: helpers.h:17
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr
Definition: helpers.h:29
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
#define WSH_NOTIFY_CONNECT_ERROR
Definition: wsahelp.h:18
#define WSH_NOTIFY_CONNECT
Definition: wsahelp.h:12

Referenced by WSPStartup().

◆ 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 }
469 if ( !(hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId)) )
471
472 /* It is a not yet duplicated socket, so map the memory, copy the SharedData and free heap */
474 {
476 NULL,
478 0,
479 (sizeof(SOCK_SHARED_INFO) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1),
480 NULL);
483 pSharedData = MapViewOfFile(Socket->SharedDataHandle,
485 0,
486 0,
487 sizeof(SOCK_SHARED_INFO));
488
489 RtlCopyMemory(pSharedData, Socket->SharedData, sizeof(SOCK_SHARED_INFO));
490 pOldSharedData = Socket->SharedData;
491 Socket->SharedData = pSharedData;
492 HeapFree(GlobalHeap, 0, pOldSharedData);
493 }
494 /* Duplicate the handles for the new process */
495 bDuplicated = DuplicateHandle(GetCurrentProcess(),
496 Socket->SharedDataHandle,
497 hProcess,
498 (LPHANDLE)&hDuplicatedSharedData,
499 0,
500 FALSE,
502 if (!bDuplicated)
503 {
506 }
507 bDuplicated = DuplicateHandle(GetCurrentProcess(),
508 (HANDLE)Socket->Handle,
509 hProcess,
510 (LPHANDLE)&hDuplicatedHandle,
511 0,
512 FALSE,
515 if( !bDuplicated )
517
518
519 if (!lpProtocolInfo)
521
522 RtlCopyMemory(lpProtocolInfo, &Socket->ProtocolInfo, sizeof(*lpProtocolInfo));
523
524 lpProtocolInfo->iAddressFamily = Socket->SharedData->AddressFamily;
525 lpProtocolInfo->iProtocol = Socket->SharedData->Protocol;
526 lpProtocolInfo->iSocketType = Socket->SharedData->SocketType;
527 lpProtocolInfo->dwServiceFlags3 = HandleToUlong(hDuplicatedSharedData);
528 lpProtocolInfo->dwServiceFlags4 = HandleToUlong(hDuplicatedHandle);
529
530 if( lpErrno )
531 *lpErrno = NO_ERROR;
532
533 return NO_ERROR;
534}
#define HandleToUlong(h)
Definition: basetsd.h:79
#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:1227
#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:99
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define CreateFileMapping
Definition: winbase.h:3621
#define FILE_MAP_ALL_ACCESS
Definition: winbase.h:156
#define DUPLICATE_SAME_ACCESS

Referenced by WSPStartup().

◆ WSPGetPeerName()

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

Definition at line 2254 of file dllmain.c.

2258{
2259 IO_STATUS_BLOCK IOSB;
2260 ULONG TdiAddressSize;
2261 PTRANSPORT_ADDRESS SocketAddress;
2262 PSOCKET_INFORMATION Socket = NULL;
2265
2266 /* Get the Socket Structure associate to this Socket*/
2267 Socket = GetSocketStructure(s);
2268 if (!Socket)
2269 {
2270 if (lpErrno) *lpErrno = WSAENOTSOCK;
2271 return SOCKET_ERROR;
2272 }
2273
2274 if (Socket->SharedData->State != SocketConnected)
2275 {
2276 if (lpErrno) *lpErrno = WSAENOTCONN;
2277 return SOCKET_ERROR;
2278 }
2279
2280 if (!Name || !NameLength)
2281 {
2282 if (lpErrno) *lpErrno = WSAEFAULT;
2283 return SOCKET_ERROR;
2284 }
2285
2288 NULL,
2290 FALSE);
2291
2292 if( !NT_SUCCESS(Status) )
2293 return SOCKET_ERROR;
2294
2295 /* Allocate a buffer for the address */
2296 TdiAddressSize = sizeof(TRANSPORT_ADDRESS) + Socket->SharedData->SizeOfRemoteAddress;
2297 SocketAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2298
2299 if ( SocketAddress == NULL )
2300 {
2301 NtClose( SockEvent );
2302 if (lpErrno) *lpErrno = WSAENOBUFS;
2303 return SOCKET_ERROR;
2304 }
2305
2306 /* Send IOCTL */
2308 SockEvent,
2309 NULL,
2310 NULL,
2311 &IOSB,
2313 NULL,
2314 0,
2315 SocketAddress,
2316 TdiAddressSize);
2317
2318 /* Wait for return */
2319 if (Status == STATUS_PENDING)
2320 {
2322 Status = IOSB.Status;
2323 }
2324
2325 NtClose( SockEvent );
2326
2327 if (NT_SUCCESS(Status))
2328 {
2329 if (*NameLength >= Socket->SharedData->SizeOfRemoteAddress)
2330 {
2331 Name->sa_family = SocketAddress->Address[0].AddressType;
2332 RtlCopyMemory (Name->sa_data,
2333 SocketAddress->Address[0].Address,
2334 SocketAddress->Address[0].AddressLength);
2335 *NameLength = Socket->SharedData->SizeOfRemoteAddress;
2336 TRACE("NameLength %d Address: %x Port %x\n",
2337 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2338 ((struct sockaddr_in *)Name)->sin_port);
2339 HeapFree(GlobalHeap, 0, SocketAddress);
2340 return 0;
2341 }
2342 else
2343 {
2344 HeapFree(GlobalHeap, 0, SocketAddress);
2345 if (lpErrno) *lpErrno = WSAEFAULT;
2346 return SOCKET_ERROR;
2347 }
2348 }
2349
2350 HeapFree(GlobalHeap, 0, SocketAddress);
2351
2352 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2353}
GLdouble s
Definition: gl.h:2039
#define IOCTL_AFD_GET_PEER_NAME
Definition: shared.h:291
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 2152 of file dllmain.c.

2156{
2157 IO_STATUS_BLOCK IOSB;
2158 ULONG TdiAddressSize;
2159 PTDI_ADDRESS_INFO TdiAddress;
2160 PTRANSPORT_ADDRESS SocketAddress;
2161 PSOCKET_INFORMATION Socket = NULL;
2164
2165 /* Get the Socket Structure associate to this Socket*/
2166 Socket = GetSocketStructure(Handle);
2167 if (!Socket)
2168 {
2169 if (lpErrno) *lpErrno = WSAENOTSOCK;
2170 return SOCKET_ERROR;
2171 }
2172
2173 if (!Name || !NameLength)
2174 {
2175 if (lpErrno) *lpErrno = WSAEFAULT;
2176 return SOCKET_ERROR;
2177 }
2178
2181 NULL,
2183 FALSE);
2184
2185 if( !NT_SUCCESS(Status) )
2186 return SOCKET_ERROR;
2187
2188 /* Allocate a buffer for the address */
2189 TdiAddressSize =
2191 TdiAddress = HeapAlloc(GlobalHeap, 0, TdiAddressSize);
2192
2193 if ( TdiAddress == NULL )
2194 {
2195 NtClose( SockEvent );
2196 if (lpErrno) *lpErrno = WSAENOBUFS;
2197 return SOCKET_ERROR;
2198 }
2199
2200 SocketAddress = &TdiAddress->Address;
2201
2202 /* Send IOCTL */
2204 SockEvent,
2205 NULL,
2206 NULL,
2207 &IOSB,
2209 NULL,
2210 0,
2211 TdiAddress,
2212 TdiAddressSize);
2213
2214 /* Wait for return */
2215 if (Status == STATUS_PENDING)
2216 {
2218 Status = IOSB.Status;
2219 }
2220
2221 NtClose( SockEvent );
2222
2223 if (NT_SUCCESS(Status))
2224 {
2225 if (*NameLength >= Socket->SharedData->SizeOfLocalAddress)
2226 {
2227 Name->sa_family = SocketAddress->Address[0].AddressType;
2228 RtlCopyMemory (Name->sa_data,
2229 SocketAddress->Address[0].Address,
2230 SocketAddress->Address[0].AddressLength);
2231 *NameLength = Socket->SharedData->SizeOfLocalAddress;
2232 TRACE("NameLength %d Address: %x Port %x\n",
2233 *NameLength, ((struct sockaddr_in *)Name)->sin_addr.s_addr,
2234 ((struct sockaddr_in *)Name)->sin_port);
2235 HeapFree(GlobalHeap, 0, TdiAddress);
2236 return 0;
2237 }
2238 else
2239 {
2240 HeapFree(GlobalHeap, 0, TdiAddress);
2241 if (lpErrno) *lpErrno = WSAEFAULT;
2242 return SOCKET_ERROR;
2243 }
2244 }
2245
2246 HeapFree(GlobalHeap, 0, TdiAddress);
2247
2248 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
2249}
#define IOCTL_AFD_GET_SOCK_NAME
Definition: shared.h:289
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 2605 of file dllmain.c.

2611{
2612 PSOCKET_INFORMATION Socket = NULL;
2613 PVOID Buffer;
2615 BOOL BoolBuffer;
2616 DWORD DwordBuffer;
2617 INT Errno;
2618
2619 TRACE("Called\n");
2620
2621 /* Get the Socket Structure associate to this Socket*/
2622 Socket = GetSocketStructure(Handle);
2623 if (Socket == NULL)
2624 {
2625 if (lpErrno) *lpErrno = WSAENOTSOCK;
2626 return SOCKET_ERROR;
2627 }
2628 if (!OptionLength || !OptionValue)
2629 {
2630 if (lpErrno) *lpErrno = WSAEFAULT;
2631 return SOCKET_ERROR;
2632 }
2633
2634 switch (Level)
2635 {
2636 case SOL_SOCKET:
2637 switch (OptionName)
2638 {
2639 case SO_TYPE:
2640 Buffer = &Socket->SharedData->SocketType;
2641 BufferSize = sizeof(INT);
2642 break;
2643
2644 case SO_RCVBUF:
2646 BufferSize = sizeof(ULONG);
2647 break;
2648
2649 case SO_SNDBUF:
2651 BufferSize = sizeof(ULONG);
2652 break;
2653
2654 case SO_ACCEPTCONN:
2655 BoolBuffer = Socket->SharedData->Listening;
2656 Buffer = &BoolBuffer;
2657 BufferSize = sizeof(BOOL);
2658 break;
2659
2660 case SO_BROADCAST:
2661 BoolBuffer = Socket->SharedData->Broadcast;
2662 Buffer = &BoolBuffer;
2663 BufferSize = sizeof(BOOL);
2664 break;
2665
2666 case SO_DEBUG:
2667 BoolBuffer = Socket->SharedData->Debug;
2668 Buffer = &BoolBuffer;
2669 BufferSize = sizeof(BOOL);
2670 break;
2671
2672 case SO_DONTLINGER:
2673 BoolBuffer = (Socket->SharedData->LingerData.l_onoff == 0);
2674 Buffer = &BoolBuffer;
2675 BufferSize = sizeof(BOOL);
2676 break;
2677
2678 case SO_LINGER:
2679 if (Socket->SharedData->SocketType == SOCK_DGRAM)
2680 {
2681 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
2682 return SOCKET_ERROR;
2683 }
2684 Buffer = &Socket->SharedData->LingerData;
2685 BufferSize = sizeof(struct linger);
2686 break;
2687
2688 case SO_OOBINLINE:
2689 BoolBuffer = (Socket->SharedData->OobInline != 0);
2690 Buffer = &BoolBuffer;
2691 BufferSize = sizeof(BOOL);
2692 break;
2693
2694 case SO_KEEPALIVE:
2695 case SO_DONTROUTE:
2696 /* These guys go directly to the helper */
2697 goto SendToHelper;
2698
2700 BoolBuffer = (Socket->SharedData->UseDelayedAcceptance != 0);
2701 Buffer = &BoolBuffer;
2702 BufferSize = sizeof(BOOL);
2703 break;
2704
2705 case SO_REUSEADDR:
2706 BoolBuffer = (Socket->SharedData->ReuseAddresses != 0);
2707 Buffer = &BoolBuffer;
2708 BufferSize = sizeof(BOOL);
2709 break;
2710
2712 BoolBuffer = (Socket->SharedData->ExclusiveAddressUse != 0);
2713 Buffer = &BoolBuffer;
2714 BufferSize = sizeof(BOOL);
2715 break;
2716
2717 case SO_ERROR:
2718 Buffer = &Socket->SharedData->SocketLastError;
2719 BufferSize = sizeof(INT);
2720 break;
2721
2722 case SO_CONNECT_TIME:
2723 DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
2724 Buffer = &DwordBuffer;
2725 BufferSize = sizeof(DWORD);
2726 break;
2727
2728 case SO_SNDTIMEO:
2729 Buffer = &Socket->SharedData->SendTimeout;
2730 BufferSize = sizeof(DWORD);
2731 break;
2732 case SO_RCVTIMEO:
2733 Buffer = &Socket->SharedData->RecvTimeout;
2734 BufferSize = sizeof(DWORD);
2735 break;
2736 case SO_PROTOCOL_INFOW:
2737 Buffer = &Socket->ProtocolInfo;
2738 BufferSize = sizeof(Socket->ProtocolInfo);
2739 break;
2740
2741 case SO_GROUP_ID:
2742 case SO_GROUP_PRIORITY:
2743 case SO_MAX_MSG_SIZE:
2744
2745 default:
2746 DbgPrint("MSAFD: Get unknown optname %x\n", OptionName);
2747 if (lpErrno) *lpErrno = WSAENOPROTOOPT;
2748 return SOCKET_ERROR;
2749 }
2750
2751 if (*OptionLength < BufferSize)
2752 {
2753 if (lpErrno) *lpErrno = WSAEFAULT;
2754 *OptionLength = BufferSize;
2755 return SOCKET_ERROR;
2756 }
2757 RtlCopyMemory(OptionValue, Buffer, BufferSize);
2758
2759 return 0;
2760
2761 default:
2762 if (lpErrno) *lpErrno = WSAEINVAL;
2763 return SOCKET_ERROR;
2764 }
2765
2766SendToHelper:
2767 Errno = Socket->HelperData->WSHGetSocketInformation(Socket->HelperContext,
2768 Handle,
2769 Socket->TdiAddressHandle,
2770 Socket->TdiConnectionHandle,
2771 Level,
2772 OptionName,
2773 OptionValue,
2774 (LPINT)OptionLength);
2775 if (lpErrno) *lpErrno = Errno;
2776 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
2777}
Definition: bufpool.h:45
#define BufferSize
Definition: mmc.h:75
#define DbgPrint
Definition: hal.h:12
#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: msafd.h:70
ULONG RecvTimeout
Definition: msafd.h:63
BOOLEAN OobInline
Definition: msafd.h:71
ULONG SizeOfSendBuffer
Definition: msafd.h:65
ULONG SizeOfRecvBuffer
Definition: msafd.h:64
ULONG SendTimeout
Definition: msafd.h:62
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
int * LPINT
Definition: windef.h:178
#define WSAENOPROTOOPT
Definition: winerror.h:1955
#define SO_PROTOCOL_INFOW
Definition: winsock2.h:249
#define SO_ERROR
Definition: winsock.h:194
#define SO_KEEPALIVE
Definition: winsock.h:181
#define SO_RCVBUF
Definition: winsock.h:189
#define SO_OOBINLINE
Definition: winsock.h:186
#define SO_DONTROUTE
Definition: winsock.h:182
#define SO_ACCEPTCONN
Definition: winsock.h:179
#define SOCK_DGRAM
Definition: winsock.h:336
#define SO_LINGER
Definition: winsock.h:185
#define SO_REUSEADDR
Definition: winsock.h:180
#define SO_TYPE
Definition: winsock.h:195
#define SOL_SOCKET
Definition: winsock.h:398
#define SO_DEBUG
Definition: winsock.h:178
#define SO_SNDTIMEO
Definition: winsock.h:192
#define SO_BROADCAST
Definition: winsock.h:183
#define SO_DONTLINGER
Definition: winsock.h:187
#define SO_RCVTIMEO
Definition: winsock.h:193
#define SO_SNDBUF
Definition: winsock.h:188
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
#define SO_CONDITIONAL_ACCEPT
Definition: ws2def.h:121
#define SO_EXCLUSIVEADDRUSE
Definition: ws2def.h:105
#define 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 2357 of file dllmain.c.

2368{
2369 PSOCKET_INFORMATION Socket = NULL;
2370 BOOL NeedsCompletion = lpOverlapped != NULL;
2371 BOOLEAN NonBlocking;
2372 INT Errno = NO_ERROR, Ret = SOCKET_ERROR;
2373 DWORD cbRet = 0;
2374
2375 /* Get the Socket Structure associate to this Socket*/
2376 Socket = GetSocketStructure(Handle);
2377 if (!Socket)
2378 {
2379 if(lpErrno)
2380 *lpErrno = WSAENOTSOCK;
2381 return SOCKET_ERROR;
2382 }
2383
2384 if (!lpcbBytesReturned && !lpOverlapped)
2385 {
2386 if(lpErrno)
2387 *lpErrno = WSAEFAULT;
2388 return SOCKET_ERROR;
2389 }
2390
2391 switch( dwIoControlCode )
2392 {
2393 case FIONBIO:
2394 if( cbInBuffer < sizeof(INT) || IS_INTRESOURCE(lpvInBuffer) )
2395 {
2396 Errno = WSAEFAULT;
2397 break;
2398 }
2399 NonBlocking = *((PULONG)lpvInBuffer) ? TRUE : FALSE;
2400 /* Don't allow to go in blocking mode if WSPAsyncSelect or WSPEventSelect is pending */
2401 if (!NonBlocking)
2402 {
2403 /* If there is an WSPAsyncSelect pending, fail with WSAEINVAL */
2404 if (Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents))
2405 {
2406 Errno = WSAEINVAL;
2407 break;
2408 }
2409 /* If there is an WSPEventSelect pending, fail with WSAEINVAL */
2410 if (Socket->NetworkEvents)
2411 {
2412 Errno = WSAEINVAL;
2413 break;
2414 }
2415 }
2416 Socket->SharedData->NonBlocking = NonBlocking ? 1 : 0;
2417 NeedsCompletion = FALSE;
2418 Errno = SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &NonBlocking, NULL, NULL, lpOverlapped, lpCompletionRoutine);
2419 if (Errno == NO_ERROR)
2420 Ret = NO_ERROR;
2421 break;
2422 case FIONREAD:
2423 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2424 {
2425 cbRet = sizeof(ULONG);
2426 Errno = WSAEFAULT;
2427 break;
2428 }
2429 if (cbOutBuffer < sizeof(ULONG))
2430 {
2431 Errno = WSAEINVAL;
2432 break;
2433 }
2434 NeedsCompletion = FALSE;
2435 Errno = GetSocketInformation(Socket, AFD_INFO_RECEIVE_CONTENT_SIZE, NULL, (PULONG)lpvOutBuffer, NULL, lpOverlapped, lpCompletionRoutine);
2436 if (Errno == NO_ERROR)
2437 {
2438 cbRet = sizeof(ULONG);
2439 Ret = NO_ERROR;
2440 }
2441 break;
2442 case SIOCATMARK:
2443 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2444 {
2445 cbRet = sizeof(BOOL);
2446 Errno = WSAEFAULT;
2447 break;
2448 }
2449 if (cbOutBuffer < sizeof(BOOL))
2450 {
2451 Errno = WSAEINVAL;
2452 break;
2453 }
2454 if (Socket->SharedData->SocketType != SOCK_STREAM)
2455 {
2456 Errno = WSAEINVAL;
2457 break;
2458 }
2459
2460 /* FIXME: Return false if OOBINLINE is true for now
2461 We should MSG_PEEK|MSG_OOB check with driver
2462 */
2463 *(BOOL*)lpvOutBuffer = !Socket->SharedData->OobInline;
2464
2465 cbRet = sizeof(BOOL);
2466 Errno = NO_ERROR;
2467 Ret = NO_ERROR;
2468 break;
2470 if (cbOutBuffer == 0)
2471 {
2472 cbRet = sizeof(PVOID);
2473 Errno = WSAEFAULT;
2474 break;
2475 }
2476
2477 if (cbInBuffer < sizeof(GUID) ||
2478 cbOutBuffer < sizeof(PVOID))
2479 {
2480 Errno = WSAEINVAL;
2481 break;
2482 }
2483
2484 {
2485 GUID AcceptExGUID = WSAID_ACCEPTEX;
2486 GUID ConnectExGUID = WSAID_CONNECTEX;
2487 GUID DisconnectExGUID = WSAID_DISCONNECTEX;
2488 GUID GetAcceptExSockaddrsGUID = WSAID_GETACCEPTEXSOCKADDRS;
2489
2490 if (IsEqualGUID(&AcceptExGUID, lpvInBuffer))
2491 {
2492 *((PVOID *)lpvOutBuffer) = WSPAcceptEx;
2493 cbRet = sizeof(PVOID);
2494 Errno = NO_ERROR;
2495 Ret = NO_ERROR;
2496 }
2497 else if (IsEqualGUID(&ConnectExGUID, lpvInBuffer))
2498 {
2499 *((PVOID *)lpvOutBuffer) = WSPConnectEx;
2500 cbRet = sizeof(PVOID);
2501 Errno = NO_ERROR;
2502 Ret = NO_ERROR;
2503 }
2504 else if (IsEqualGUID(&DisconnectExGUID, lpvInBuffer))
2505 {
2506 *((PVOID *)lpvOutBuffer) = WSPDisconnectEx;
2507 cbRet = sizeof(PVOID);
2508 Errno = NO_ERROR;
2509 Ret = NO_ERROR;
2510 }
2511 else if (IsEqualGUID(&GetAcceptExSockaddrsGUID, lpvInBuffer))
2512 {
2513 *((PVOID *)lpvOutBuffer) = WSPGetAcceptExSockaddrs;
2514 cbRet = sizeof(PVOID);
2515 Errno = NO_ERROR;
2516 /* See CORE-14966 and associated commits.
2517 * Original line below was 'Ret = NO_ERROR:'.
2518 * This caused winetest ws2_32:sock to hang.
2519 * This new Ret value allows the test to complete. */
2520 ERR("SIO_GET_EXTENSION_FUNCTION_POINTER UNIMPLEMENTED\n");
2521 Ret = SOCKET_ERROR;
2522 }
2523 else
2524 {
2525 ERR("Querying unknown extension function: %x\n", ((GUID*)lpvInBuffer)->Data1);
2526 Errno = WSAEOPNOTSUPP;
2527 }
2528 }
2529
2530 break;
2532 if (IS_INTRESOURCE(lpvOutBuffer) || cbOutBuffer == 0)
2533 {
2534 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2535 Errno = WSAEFAULT;
2536 break;
2537 }
2538 if (cbOutBuffer < sizeof(INT))
2539 {
2540 Errno = WSAEINVAL;
2541 break;
2542 }
2543
2544 cbRet = sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress);
2545
2546 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->iAddressCount = 1;
2547
2548 if (cbOutBuffer < (sizeof(SOCKET_ADDRESS_LIST) + sizeof(Socket->SharedData->WSLocalAddress)))
2549 {
2550 Errno = WSAEFAULT;
2551 break;
2552 }
2553
2554 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].iSockaddrLength = sizeof(Socket->SharedData->WSLocalAddress);
2555 ((SOCKET_ADDRESS_LIST*)lpvOutBuffer)->Address[0].lpSockaddr = &Socket->SharedData->WSLocalAddress;
2556
2557 Errno = NO_ERROR;
2558 Ret = NO_ERROR;
2559 break;
2560 default:
2561 Errno = Socket->HelperData->WSHIoctl(Socket->HelperContext,
2562 Handle,
2563 Socket->TdiAddressHandle,
2564 Socket->TdiConnectionHandle,
2566 lpvInBuffer,
2567 cbInBuffer,
2568 lpvOutBuffer,
2569 cbOutBuffer,
2570 &cbRet,
2572 lpCompletionRoutine,
2573 &NeedsCompletion);
2574
2575 if (Errno == NO_ERROR)
2576 Ret = NO_ERROR;
2577 break;
2578 }
2579 if (lpOverlapped && NeedsCompletion)
2580 {
2581 lpOverlapped->Internal = Errno;
2582 lpOverlapped->InternalHigh = cbRet;
2583 if (lpCompletionRoutine != NULL)
2584 {
2585 lpCompletionRoutine(Errno, cbRet, lpOverlapped, 0);
2586 }
2587 if (lpOverlapped->hEvent)
2588 SetEvent(lpOverlapped->hEvent);
2590 {
2591 ERR("PostQueuedCompletionStatus failed %d\n", GetLastError());
2592 }
2593 return NO_ERROR;
2594 }
2595 if (lpErrno)
2596 *lpErrno = Errno;
2597 if (lpcbBytesReturned)
2598 *lpcbBytesReturned = cbRet;
2599 return Ret;
2600}
unsigned char BOOLEAN
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:3393
BOOL WSPAPI WSPConnectEx(IN SOCKET s, IN const struct sockaddr *name, IN int namelen, IN PVOID lpSendBuffer, IN DWORD dwSendDataLength, OUT LPDWORD lpdwBytesSent, IN OUT LPOVERLAPPED lpOverlapped)
Definition: stubs.c:75
BOOL WSPAPI WSPAcceptEx(IN SOCKET sListenSocket, IN SOCKET sAcceptSocket, OUT PVOID lpOutputBuffer, IN DWORD dwReceiveDataLength, IN DWORD dwLocalAddressLength, IN DWORD dwRemoteAddressLength, OUT LPDWORD lpdwBytesReceived, IN OUT LPOVERLAPPED lpOverlapped)
Definition: stubs.c:58
VOID WSPAPI WSPGetAcceptExSockaddrs(IN PVOID lpOutputBuffer, IN DWORD dwReceiveDataLength, IN DWORD dwLocalAddressLength, IN DWORD dwRemoteAddressLength, OUT struct sockaddr **LocalSockaddr, OUT LPINT LocalSockaddrLength, OUT struct sockaddr **RemoteSockaddr, OUT LPINT RemoteSockaddrLength)
Definition: stubs.c:104
BOOL WSPAPI WSPDisconnectEx(IN SOCKET hSocket, IN LPOVERLAPPED lpOverlapped, IN DWORD dwFlags, IN DWORD reserved)
Definition: stubs.c:91
#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
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:93
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define AFD_INFO_RECEIVE_CONTENT_SIZE
Definition: shared.h:188
#define AFD_INFO_BLOCKING_MODE
Definition: shared.h:183
PWSH_IOCTL WSHIoctl
Definition: helpers.h:33
LONG NetworkEvents
Definition: msafd.h:111
SOCKADDR WSLocalAddress
Definition: msafd.h:94
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
uint32_t * PULONG
Definition: typedefs.h:59
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
_In_ DWORD dwIoControlCode
Definition: winddi.h:1700
#define SIOCATMARK
Definition: winsock.h:253
#define FIONREAD
Definition: winsock.h:247
#define FIONBIO
Definition: winsock.h:149
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#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 981 of file dllmain.c.

984{
985 IO_STATUS_BLOCK IOSB;
986 AFD_LISTEN_DATA ListenData;
987 PSOCKET_INFORMATION Socket = NULL;
990
991 /* Get the Socket Structure associate to this Socket*/
992 Socket = GetSocketStructure(Handle);
993 if (!Socket)
994 {
995 if (lpErrno) *lpErrno = WSAENOTSOCK;
996 return SOCKET_ERROR;
997 }
998
999 if (Socket->SharedData->Listening)
1000 return NO_ERROR;
1001
1004 NULL,
1006 FALSE);
1007
1008 if( !NT_SUCCESS(Status) )
1009 return SOCKET_ERROR;
1010
1011 /* Set Up Listen Structure */
1012 ListenData.UseSAN = FALSE;
1014 ListenData.Backlog = Backlog;
1015
1016 /* Send IOCTL */
1018 SockEvent,
1019 NULL,
1020 NULL,
1021 &IOSB,
1023 &ListenData,
1024 sizeof(ListenData),
1025 NULL,
1026 0);
1027
1028 /* Wait for return */
1029 if (Status == STATUS_PENDING)
1030 {
1032 Status = IOSB.Status;
1033 }
1034
1035 NtClose( SockEvent );
1036
1038 if (Status != STATUS_SUCCESS)
1039 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1040
1041 /* Set to Listening */
1042 Socket->SharedData->Listening = TRUE;
1043
1044 if (Socket->HelperEvents & WSH_NOTIFY_LISTEN)
1045 {
1046 Status = Socket->HelperData->WSHNotify(Socket->HelperContext,
1047 Socket->Handle,
1048 Socket->TdiAddressHandle,
1049 Socket->TdiConnectionHandle,
1051
1052 if (Status)
1053 {
1054 if (lpErrno) *lpErrno = Status;
1055 return SOCKET_ERROR;
1056 }
1057 }
1058
1059 return MsafdReturnWithErrno ( Status, lpErrno, 0, NULL );
1060}
#define IOCTL_AFD_START_LISTEN
Definition: shared.h:271
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 1065 of file dllmain.c.

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

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 2781 of file dllmain.c.

2788{
2789 PSOCKET_INFORMATION Socket;
2790 INT Errno;
2791
2792 /* Get the Socket Structure associate to this Socket*/
2793 Socket = GetSocketStructure(s);
2794 if (Socket == NULL)
2795 {
2796 if (lpErrno) *lpErrno = WSAENOTSOCK;
2797 return SOCKET_ERROR;
2798 }
2799 if (!optval)
2800 {
2801 if (lpErrno) *lpErrno = WSAEFAULT;
2802 return SOCKET_ERROR;
2803 }
2804
2805
2806 /* FIXME: We should handle some more cases here */
2807 if (level == SOL_SOCKET)
2808 {
2809 switch (optname)
2810 {
2811 case SO_BROADCAST:
2812 if (optlen < sizeof(BOOL))
2813 {
2814 if (lpErrno) *lpErrno = WSAEFAULT;
2815 return SOCKET_ERROR;
2816 }
2817 Socket->SharedData->Broadcast = (*optval != 0) ? 1 : 0;
2818 return NO_ERROR;
2819
2820 case SO_OOBINLINE:
2821 if (optlen < sizeof(BOOL))
2822 {
2823 if (lpErrno) *lpErrno = WSAEFAULT;
2824 return SOCKET_ERROR;
2825 }
2826 Socket->SharedData->OobInline = (*optval != 0) ? 1 : 0;
2827 return NO_ERROR;
2828
2829 case SO_DONTLINGER:
2830 if (optlen < sizeof(BOOL))
2831 {
2832 if (lpErrno) *lpErrno = WSAEFAULT;
2833 return SOCKET_ERROR;
2834 }
2835 Socket->SharedData->LingerData.l_onoff = (*optval != 0) ? 0 : 1;
2836 return NO_ERROR;
2837
2838 case SO_REUSEADDR:
2839 if (optlen < sizeof(BOOL))
2840 {
2841 if (lpErrno) *lpErrno = WSAEFAULT;
2842 return SOCKET_ERROR;
2843 }
2844 Socket->SharedData->ReuseAddresses = (*optval != 0) ? 1 : 0;
2845 return NO_ERROR;
2846
2848 if (optlen < sizeof(BOOL))
2849 {
2850 if (lpErrno) *lpErrno = WSAEFAULT;
2851 return SOCKET_ERROR;
2852 }
2853 Socket->SharedData->ExclusiveAddressUse = (*optval != 0) ? 1 : 0;
2854 return NO_ERROR;
2855
2856 case SO_LINGER:
2857 if (optlen < sizeof(struct linger))
2858 {
2859 if (lpErrno) *lpErrno = WSAEFAULT;
2860 return SOCKET_ERROR;
2861 }
2863 optval,
2864 sizeof(struct linger));
2865 return NO_ERROR;
2866
2867 case SO_SNDBUF:
2868 if (optlen < sizeof(ULONG))
2869 {
2870 if (lpErrno) *lpErrno = WSAEFAULT;
2871 return SOCKET_ERROR;
2872 }
2873
2874 SetSocketInformation(Socket,
2876 NULL,
2877 (PULONG)optval,
2878 NULL,
2879 NULL,
2880 NULL);
2881 GetSocketInformation(Socket,
2883 NULL,
2884 &Socket->SharedData->SizeOfSendBuffer,
2885 NULL,
2886 NULL,
2887 NULL);
2888
2889 return NO_ERROR;
2890
2891 case SO_RCVBUF:
2892 if (optlen < sizeof(ULONG))
2893 {
2894 if (lpErrno) *lpErrno = WSAEFAULT;
2895 return SOCKET_ERROR;
2896 }
2897
2898 /* FIXME: We should not have to limit the packet receive buffer size like this. workaround for CORE-15804 */
2899 if (*(PULONG)optval > 0x2000)
2900 *(PULONG)optval = 0x2000;
2901
2902 SetSocketInformation(Socket,
2904 NULL,
2905 (PULONG)optval,
2906 NULL,
2907 NULL,
2908 NULL);
2909 GetSocketInformation(Socket,
2911 NULL,
2912 &Socket->SharedData->SizeOfRecvBuffer,
2913 NULL,
2914 NULL,
2915 NULL);
2916
2917 return NO_ERROR;
2918
2919 case SO_ERROR:
2920 if (optlen < sizeof(INT))
2921 {
2922 if (lpErrno) *lpErrno = WSAEFAULT;
2923 return SOCKET_ERROR;
2924 }
2925
2927 optval,
2928 sizeof(INT));
2929 return NO_ERROR;
2930
2931 case SO_SNDTIMEO:
2932 if (optlen < sizeof(DWORD))
2933 {
2934 if (lpErrno) *lpErrno = WSAEFAULT;
2935 return SOCKET_ERROR;
2936 }
2937
2939 optval,
2940 sizeof(DWORD));
2941 return NO_ERROR;
2942
2943 case SO_RCVTIMEO:
2944 if (optlen < sizeof(DWORD))
2945 {
2946 if (lpErrno) *lpErrno = WSAEFAULT;
2947 return SOCKET_ERROR;
2948 }
2949
2951 optval,
2952 sizeof(DWORD));
2953 return NO_ERROR;
2954
2955 case SO_KEEPALIVE:
2956 case SO_DONTROUTE:
2957 /* These go directly to the helper dll */
2958 goto SendToHelper;
2959
2960 default:
2961 /* Obviously this is a hack */
2962 ERR("MSAFD: Set unknown optname %x\n", optname);
2963 return NO_ERROR;
2964 }
2965 }
2966
2967SendToHelper:
2968 Errno = Socket->HelperData->WSHSetSocketInformation(Socket->HelperContext,
2969 s,
2970 Socket->TdiAddressHandle,
2971 Socket->TdiConnectionHandle,
2972 level,
2973 optname,
2974 (PCHAR)optval,
2975 optlen);
2976 if (lpErrno) *lpErrno = Errno;
2977 return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
2978}
GLint level
Definition: gl.h:1546
#define AFD_INFO_SEND_WINDOW_SIZE
Definition: shared.h:186
#define AFD_INFO_RECEIVE_WINDOW_SIZE
Definition: shared.h:185
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 2072 of file dllmain.c.

2076{
2077 IO_STATUS_BLOCK IOSB;
2078 AFD_DISCONNECT_INFO DisconnectInfo;
2079 PSOCKET_INFORMATION Socket = NULL;
2082
2083 TRACE("Called\n");
2084
2085 /* Get the Socket Structure associate to this Socket*/
2086 Socket = GetSocketStructure(Handle);
2087 if (!Socket)
2088 {
2089 if (lpErrno) *lpErrno = WSAENOTSOCK;
2090 return SOCKET_ERROR;
2091 }
2092
2095 NULL,
2097 FALSE);
2098
2099 if( !NT_SUCCESS(Status) )
2100 return SOCKET_ERROR;
2101
2102 /* Set AFD Disconnect Type */
2103 switch (HowTo)
2104 {
2105 case SD_RECEIVE:
2106 DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV;
2107 Socket->SharedData->ReceiveShutdown = TRUE;
2108 break;
2109 case SD_SEND:
2110 DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND;
2111 Socket->SharedData->SendShutdown = TRUE;
2112 break;
2113 case SD_BOTH:
2115 Socket->SharedData->ReceiveShutdown = TRUE;
2116 Socket->SharedData->SendShutdown = TRUE;
2117 break;
2118 }
2119
2120 DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1000000);
2121
2122 /* Send IOCTL */
2124 SockEvent,
2125 NULL,
2126 NULL,
2127 &IOSB,
2129 &DisconnectInfo,
2130 sizeof(DisconnectInfo),
2131 NULL,
2132 0);
2133
2134 /* Wait for return */
2135 if (Status == STATUS_PENDING)
2136 {
2138 Status = IOSB.Status;
2139 }
2140
2141 TRACE("Ending\n");
2142
2143 NtClose( SockEvent );
2144
2146 return MsafdReturnWithErrno( Status, lpErrno, 0, NULL );
2147}
#define AFD_DISCONNECT_RECV
Definition: shared.h:198
#define SD_BOTH
Definition: winsock.h:56
#define SD_SEND
Definition: winsock.h:55
#define SD_RECEIVE
Definition: winsock.h:54

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