mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[MSAFD] Implement WSPGetOverlappedResult. Reviewed by Thomas and Art. Thanks! CORE-12134 #resolve
svn path=/trunk/; revision=72966
This commit is contained in:
parent
24100643a9
commit
a82f4b1f38
3 changed files with 212 additions and 36 deletions
|
@ -94,6 +94,92 @@ WSPAsyncSelect(IN SOCKET Handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
WSPAPI
|
||||||
|
WSPGetOverlappedResult(
|
||||||
|
IN SOCKET Handle,
|
||||||
|
IN LPWSAOVERLAPPED lpOverlapped,
|
||||||
|
OUT LPDWORD lpdwBytes,
|
||||||
|
IN BOOL fWait,
|
||||||
|
OUT LPDWORD lpdwFlags,
|
||||||
|
OUT LPINT lpErrno)
|
||||||
|
{
|
||||||
|
PIO_STATUS_BLOCK IOSB;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PSOCKET_INFORMATION Socket;
|
||||||
|
|
||||||
|
TRACE("Called (%x)\n", Handle);
|
||||||
|
|
||||||
|
/* Get the Socket Structure associate to this Socket*/
|
||||||
|
Socket = GetSocketStructure(Handle);
|
||||||
|
if (!Socket)
|
||||||
|
{
|
||||||
|
if(lpErrno)
|
||||||
|
*lpErrno = WSAENOTSOCK;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!lpOverlapped || !lpdwBytes || !lpdwFlags)
|
||||||
|
{
|
||||||
|
if (lpErrno)
|
||||||
|
*lpErrno = WSAEFAULT;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
|
||||||
|
if (!IOSB)
|
||||||
|
{
|
||||||
|
if (lpErrno)
|
||||||
|
*lpErrno = WSAEFAULT;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
Status = IOSB->Status;
|
||||||
|
|
||||||
|
/* Wait for completition of overlapped */
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* It's up to the protocol to time out recv. We must wait
|
||||||
|
* until the protocol decides it's had enough.
|
||||||
|
*/
|
||||||
|
if (fWait)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(lpOverlapped->hEvent, INFINITE);
|
||||||
|
Status = IOSB->Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Status %x Information %d\n", Status, IOSB->Information);
|
||||||
|
|
||||||
|
if (Status != STATUS_PENDING)
|
||||||
|
{
|
||||||
|
*lpdwFlags = 0;
|
||||||
|
|
||||||
|
*lpdwBytes = IOSB->Information;
|
||||||
|
|
||||||
|
/* Re-enable Async Event */
|
||||||
|
SockReenableAsyncSelectEvent(Socket, FD_OOB);
|
||||||
|
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
|
||||||
|
SockReenableAsyncSelectEvent(Socket, FD_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status == STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
AfdAPC(PVOID ApcContext,
|
||||||
|
PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
|
ULONG Reserved)
|
||||||
|
{
|
||||||
|
PAFDAPCCONTEXT Context = ApcContext;
|
||||||
|
|
||||||
|
/* Re-enable Async Event */
|
||||||
|
SockReenableAsyncSelectEvent(Context->lpSocket, FD_OOB);
|
||||||
|
SockReenableAsyncSelectEvent(Context->lpSocket, FD_READ);
|
||||||
|
SockReenableAsyncSelectEvent(Context->lpSocket, FD_WRITE);
|
||||||
|
|
||||||
|
Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
|
||||||
|
HeapFree(GlobalHeap, 0, ApcContext);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
WSPAPI
|
WSPAPI
|
||||||
WSPRecv(SOCKET Handle,
|
WSPRecv(SOCKET Handle,
|
||||||
|
@ -111,7 +197,7 @@ WSPRecv(SOCKET Handle,
|
||||||
AFD_RECV_INFO RecvInfo;
|
AFD_RECV_INFO RecvInfo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PVOID APCContext;
|
PVOID APCContext;
|
||||||
PVOID APCFunction;
|
PIO_APC_ROUTINE APCFunction;
|
||||||
HANDLE Event = NULL;
|
HANDLE Event = NULL;
|
||||||
HANDLE SockEvent;
|
HANDLE SockEvent;
|
||||||
PSOCKET_INFORMATION Socket;
|
PSOCKET_INFORMATION Socket;
|
||||||
|
@ -173,6 +259,12 @@ WSPRecv(SOCKET Handle,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Overlapped request for non overlapped opened socket */
|
||||||
|
if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
|
||||||
|
{
|
||||||
|
TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
|
||||||
|
return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesRead);
|
||||||
|
}
|
||||||
if (lpCompletionRoutine == NULL)
|
if (lpCompletionRoutine == NULL)
|
||||||
{
|
{
|
||||||
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
||||||
|
@ -183,8 +275,16 @@ WSPRecv(SOCKET Handle,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
||||||
APCFunction = NULL; // should be a private io completition function inside us
|
APCFunction = &AfdAPC; // should be a private io completition function inside us
|
||||||
APCContext = lpCompletionRoutine;
|
APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
|
||||||
|
if (!APCContext)
|
||||||
|
{
|
||||||
|
ERR("Not enough memory for APC Context\n");
|
||||||
|
return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesRead);
|
||||||
|
}
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
|
||||||
RecvInfo.AfdFlags |= AFD_SKIP_FIO;
|
RecvInfo.AfdFlags |= AFD_SKIP_FIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,15 +296,15 @@ WSPRecv(SOCKET Handle,
|
||||||
|
|
||||||
/* Send IOCTL */
|
/* Send IOCTL */
|
||||||
Status = NtDeviceIoControlFile((HANDLE)Handle,
|
Status = NtDeviceIoControlFile((HANDLE)Handle,
|
||||||
Event,
|
Event,
|
||||||
APCFunction,
|
APCFunction,
|
||||||
APCContext,
|
APCContext,
|
||||||
IOSB,
|
IOSB,
|
||||||
IOCTL_AFD_RECV,
|
IOCTL_AFD_RECV,
|
||||||
&RecvInfo,
|
&RecvInfo,
|
||||||
sizeof(RecvInfo),
|
sizeof(RecvInfo),
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
/* Wait for completition of not overlapped */
|
/* Wait for completition of not overlapped */
|
||||||
if (Status == STATUS_PENDING && lpOverlapped == NULL)
|
if (Status == STATUS_PENDING && lpOverlapped == NULL)
|
||||||
|
@ -220,6 +320,12 @@ WSPRecv(SOCKET Handle,
|
||||||
|
|
||||||
TRACE("Status %x Information %d\n", Status, IOSB->Information);
|
TRACE("Status %x Information %d\n", Status, IOSB->Information);
|
||||||
|
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
TRACE("Leaving (Pending)\n");
|
||||||
|
return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the Flags */
|
/* Return the Flags */
|
||||||
*ReceiveFlags = 0;
|
*ReceiveFlags = 0;
|
||||||
|
|
||||||
|
@ -246,6 +352,12 @@ WSPRecv(SOCKET Handle,
|
||||||
SockReenableAsyncSelectEvent(Socket, FD_READ);
|
SockReenableAsyncSelectEvent(Socket, FD_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
|
||||||
|
{
|
||||||
|
lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, *ReceiveFlags);
|
||||||
|
HeapFree(GlobalHeap, 0, (PVOID)APCContext);
|
||||||
|
}
|
||||||
|
|
||||||
return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
|
return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,6 +467,12 @@ WSPRecvFrom(SOCKET Handle,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Overlapped request for non overlapped opened socket */
|
||||||
|
if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
|
||||||
|
{
|
||||||
|
TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
|
||||||
|
return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesRead);
|
||||||
|
}
|
||||||
if (lpCompletionRoutine == NULL)
|
if (lpCompletionRoutine == NULL)
|
||||||
{
|
{
|
||||||
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
||||||
|
@ -365,8 +483,16 @@ WSPRecvFrom(SOCKET Handle,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
||||||
APCFunction = NULL; // should be a private io completition function inside us
|
APCFunction = &AfdAPC; // should be a private io completition function inside us
|
||||||
APCContext = lpCompletionRoutine;
|
APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
|
||||||
|
if (!APCContext)
|
||||||
|
{
|
||||||
|
ERR("Not enough memory for APC Context\n");
|
||||||
|
return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesRead);
|
||||||
|
}
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
|
||||||
RecvInfo.AfdFlags |= AFD_SKIP_FIO;
|
RecvInfo.AfdFlags |= AFD_SKIP_FIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,12 +523,19 @@ WSPRecvFrom(SOCKET Handle,
|
||||||
|
|
||||||
NtClose( SockEvent );
|
NtClose( SockEvent );
|
||||||
|
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
TRACE("Leaving (Pending)\n");
|
||||||
|
return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the Flags */
|
/* Return the Flags */
|
||||||
*ReceiveFlags = 0;
|
*ReceiveFlags = 0;
|
||||||
|
|
||||||
switch (Status)
|
switch (Status)
|
||||||
{
|
{
|
||||||
case STATUS_RECEIVE_EXPEDITED: *ReceiveFlags = MSG_OOB;
|
case STATUS_RECEIVE_EXPEDITED:
|
||||||
|
*ReceiveFlags = MSG_OOB;
|
||||||
break;
|
break;
|
||||||
case STATUS_RECEIVE_PARTIAL_EXPEDITED:
|
case STATUS_RECEIVE_PARTIAL_EXPEDITED:
|
||||||
*ReceiveFlags = MSG_PARTIAL | MSG_OOB;
|
*ReceiveFlags = MSG_PARTIAL | MSG_OOB;
|
||||||
|
@ -422,6 +555,12 @@ WSPRecvFrom(SOCKET Handle,
|
||||||
SockReenableAsyncSelectEvent(Socket, FD_READ);
|
SockReenableAsyncSelectEvent(Socket, FD_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
|
||||||
|
{
|
||||||
|
lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, *ReceiveFlags);
|
||||||
|
HeapFree(GlobalHeap, 0, (PVOID)APCContext);
|
||||||
|
}
|
||||||
|
|
||||||
return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
|
return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,6 +633,12 @@ WSPSend(SOCKET Handle,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Overlapped request for non overlapped opened socket */
|
||||||
|
if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
|
||||||
|
{
|
||||||
|
TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
|
||||||
|
return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesSent);
|
||||||
|
}
|
||||||
if (lpCompletionRoutine == NULL)
|
if (lpCompletionRoutine == NULL)
|
||||||
{
|
{
|
||||||
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
||||||
|
@ -504,8 +649,16 @@ WSPSend(SOCKET Handle,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
||||||
APCFunction = NULL; // should be a private io completition function inside us
|
APCFunction = &AfdAPC; // should be a private io completition function inside us
|
||||||
APCContext = lpCompletionRoutine;
|
APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
|
||||||
|
if (!APCContext)
|
||||||
|
{
|
||||||
|
ERR("Not enough memory for APC Context\n");
|
||||||
|
return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesSent);
|
||||||
|
}
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
|
||||||
SendInfo.AfdFlags |= AFD_SKIP_FIO;
|
SendInfo.AfdFlags |= AFD_SKIP_FIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,6 +700,12 @@ WSPSend(SOCKET Handle,
|
||||||
|
|
||||||
TRACE("Leaving (Success, %d)\n", IOSB->Information);
|
TRACE("Leaving (Success, %d)\n", IOSB->Information);
|
||||||
|
|
||||||
|
if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
|
||||||
|
{
|
||||||
|
lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, 0);
|
||||||
|
HeapFree(GlobalHeap, 0, (PVOID)APCContext);
|
||||||
|
}
|
||||||
|
|
||||||
return MsafdReturnWithErrno( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent );
|
return MsafdReturnWithErrno( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,6 +825,12 @@ WSPSendTo(SOCKET Handle,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Overlapped request for non overlapped opened socket */
|
||||||
|
if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
|
||||||
|
{
|
||||||
|
TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
|
||||||
|
return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesSent);
|
||||||
|
}
|
||||||
if (lpCompletionRoutine == NULL)
|
if (lpCompletionRoutine == NULL)
|
||||||
{
|
{
|
||||||
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
/* Using Overlapped Structure, but no Completition Routine, so no need for APC */
|
||||||
|
@ -676,9 +841,16 @@ WSPSendTo(SOCKET Handle,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
/* Using Overlapped Structure and a Completition Routine, so use an APC */
|
||||||
/* Should be a private io completition function inside us */
|
APCFunction = &AfdAPC; // should be a private io completition function inside us
|
||||||
APCFunction = NULL;
|
APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
|
||||||
APCContext = lpCompletionRoutine;
|
if (!APCContext)
|
||||||
|
{
|
||||||
|
ERR("Not enough memory for APC Context\n");
|
||||||
|
return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesSent);
|
||||||
|
}
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
|
||||||
|
((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
|
||||||
SendInfo.AfdFlags |= AFD_SKIP_FIO;
|
SendInfo.AfdFlags |= AFD_SKIP_FIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,8 +885,20 @@ WSPSendTo(SOCKET Handle,
|
||||||
HeapFree(GlobalHeap, 0, BindAddress);
|
HeapFree(GlobalHeap, 0, BindAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
TRACE("Leaving (Pending)\n");
|
||||||
|
return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
|
||||||
|
}
|
||||||
|
|
||||||
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
|
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
|
||||||
|
|
||||||
|
if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
|
||||||
|
{
|
||||||
|
lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, 0);
|
||||||
|
HeapFree(GlobalHeap, 0, (PVOID)APCContext);
|
||||||
|
}
|
||||||
|
|
||||||
return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
|
return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,22 +24,6 @@ WSPCancelBlockingCall(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
WSPAPI
|
|
||||||
WSPGetOverlappedResult(
|
|
||||||
IN SOCKET s,
|
|
||||||
IN LPWSAOVERLAPPED lpOverlapped,
|
|
||||||
OUT LPDWORD lpcbTransfer,
|
|
||||||
IN BOOL fWait,
|
|
||||||
OUT LPDWORD lpdwFlags,
|
|
||||||
OUT LPINT lpErrno)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
WSPAPI
|
WSPAPI
|
||||||
WSPGetQOSByName(
|
WSPGetQOSByName(
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <wsahelp.h>
|
#include <wsahelp.h>
|
||||||
#include <tdi.h>
|
#include <tdi.h>
|
||||||
#include <afd/shared.h>
|
#include <afd/shared.h>
|
||||||
|
#include <mswsock.h>
|
||||||
#include "include/helpers.h"
|
#include "include/helpers.h"
|
||||||
|
|
||||||
extern HANDLE GlobalHeap;
|
extern HANDLE GlobalHeap;
|
||||||
|
@ -127,6 +128,13 @@ typedef struct _ASYNC_DATA {
|
||||||
AFD_POLL_INFO AsyncSelectInfo;
|
AFD_POLL_INFO AsyncSelectInfo;
|
||||||
} ASYNC_DATA, *PASYNC_DATA;
|
} ASYNC_DATA, *PASYNC_DATA;
|
||||||
|
|
||||||
|
typedef struct _AFDAPCCONTEXT
|
||||||
|
{
|
||||||
|
LPWSAOVERLAPPED lpOverlapped;
|
||||||
|
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine;
|
||||||
|
PSOCKET_INFORMATION lpSocket;
|
||||||
|
} AFDAPCCONTEXT, *PAFDAPCCONTEXT;
|
||||||
|
|
||||||
SOCKET
|
SOCKET
|
||||||
WSPAPI
|
WSPAPI
|
||||||
WSPAccept(
|
WSPAccept(
|
||||||
|
|
Loading…
Reference in a new issue