📄 spi.cpp
字号:
if (SocketContext == NULL)
{
dbgprint("WSPListen: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPListen(
SocketContext->ProviderSocket,
backlog,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPRecv
//
// Description:
// This function receives data on a given socket and also allows for asynchronous
// (overlapped) operation. First translate the socket handle to the lower provider
// handle and then make the receive call. If called with overlap, post the operation
// to our IOCP or completion routine.
//
int WSPAPI WSPRecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno)
{
LPWSAOVERLAPPEDPLUS ProviderOverlapped;
SOCK_INFO *SocketContext;
int ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPRecv: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
//
// Check for overlapped I/O
//
if (lpOverlapped)
{
ProviderOverlapped = GetOverlappedStructure(SocketContext);
if (!ProviderOverlapped)
{
UnlockSocketContext(SocketContext, lpErrno);
dbgprint("WSPRecv: GetOverlappedStructure() returned NULL");
*lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
CopyOffset(&ProviderOverlapped->ProviderOverlapped, lpOverlapped);
ProviderOverlapped->SockInfo = SocketContext;
ProviderOverlapped->CallerSocket = s;
ProviderOverlapped->ProviderSocket = SocketContext->ProviderSocket;
ProviderOverlapped->Error = NO_ERROR;
ProviderOverlapped->Operation = LSP_OP_RECV;
ProviderOverlapped->lpCallerThreadId = lpThreadId;
ProviderOverlapped->lpCallerCompletionRoutine = lpCompletionRoutine;
ProviderOverlapped->RecvArgs.lpBuffers = CopyBuffer(lpBuffers, dwBufferCount);
ProviderOverlapped->RecvArgs.dwBufferCount = dwBufferCount;
ProviderOverlapped->RecvArgs.dwNumberOfBytesRecvd = (lpNumberOfBytesRecvd ? *lpNumberOfBytesRecvd : 0);
ProviderOverlapped->RecvArgs.dwFlags = (lpFlags ? *lpFlags : 0);
ProviderOverlapped->Provider = SocketContext->Provider;
ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);
if (ret != NO_ERROR)
{
*lpErrno = ret;
ret = SOCKET_ERROR;
}
}
else
{
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPRecv(
SocketContext->ProviderSocket,
lpBuffers,
dwBufferCount,
lpNumberOfBytesRecvd,
lpFlags,
lpOverlapped,
lpCompletionRoutine,
lpThreadId,
lpErrno);
SetBlockingProvider(NULL);
if (ret != SOCKET_ERROR)
{
SocketContext->BytesRecv += *lpNumberOfBytesRecvd;
}
}
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPRecvDisconnect
//
// Description:
// Receive data and disconnect. All we need to do is translate the socket
// handle to the lower provider.
//
int WSPAPI WSPRecvDisconnect(
SOCKET s,
LPWSABUF lpInboundDisconnectData,
LPINT lpErrno)
{
SOCK_INFO *SocketContext;
INT ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPRecvDisconnect: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPRecvDisconnect(
SocketContext->ProviderSocket,
lpInboundDisconnectData,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPRecvFrom
//
// Description:
// This function receives data on a given socket and also allows for asynchronous
// (overlapped) operation. First translate the socket handle to the lower provider
// handle and then make the receive call. If called with overlap, post the operation
// to our IOCP or completion routine.
//
int WSPAPI WSPRecvFrom(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
struct sockaddr FAR * lpFrom,
LPINT lpFromLen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno)
{
LPWSAOVERLAPPEDPLUS ProviderOverlapped;
SOCK_INFO *SocketContext;
int ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPRecvFrom: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
//
// Check for overlapped I/O
//
if (lpOverlapped)
{
ProviderOverlapped = GetOverlappedStructure(SocketContext);
if (!ProviderOverlapped)
{
UnlockSocketContext(SocketContext, lpErrno);
dbgprint("WSPRecvFrom: GetOverlappedStructure() returned NULL");
*lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
ProviderOverlapped->lpCallerOverlapped = lpOverlapped;
CopyOffset(&ProviderOverlapped->ProviderOverlapped, lpOverlapped);
ProviderOverlapped->SockInfo = SocketContext;
ProviderOverlapped->CallerSocket = s;
ProviderOverlapped->ProviderSocket = SocketContext->ProviderSocket;
ProviderOverlapped->Error = NO_ERROR;
ProviderOverlapped->Operation = LSP_OP_RECVFROM;
ProviderOverlapped->lpCallerThreadId = lpThreadId;
ProviderOverlapped->lpCallerCompletionRoutine = lpCompletionRoutine;
ProviderOverlapped->RecvFromArgs.lpBuffers = CopyBuffer(lpBuffers, dwBufferCount);
ProviderOverlapped->RecvFromArgs.dwBufferCount = dwBufferCount;
ProviderOverlapped->RecvFromArgs.dwNumberOfBytesRecvd = (lpNumberOfBytesRecvd ? *lpNumberOfBytesRecvd : 0);
ProviderOverlapped->RecvFromArgs.dwFlags = (lpFlags ? *lpFlags : 0);
ProviderOverlapped->RecvFromArgs.lpFrom = lpFrom;
ProviderOverlapped->RecvFromArgs.lpFromLen = lpFromLen;
ProviderOverlapped->Provider = SocketContext->Provider;
ret = QueueOverlappedOperation(ProviderOverlapped, SocketContext);
if (ret != NO_ERROR)
{
*lpErrno = ret;
ret = SOCKET_ERROR;
}
}
else
{
// Make a blocking WSPRecvFrom call
//
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPRecvFrom(
SocketContext->ProviderSocket,
lpBuffers,
dwBufferCount,
lpNumberOfBytesRecvd,
lpFlags,
lpFrom,
lpFromLen,
lpOverlapped,
lpCompletionRoutine,
lpThreadId,
lpErrno);
SetBlockingProvider(NULL);
if (ret != SOCKET_ERROR)
{
SocketContext->BytesRecv += *lpNumberOfBytesRecvd;
}
}
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPSelect
//
// Description:
// This function tests a set of sockets for readability, writeability, and
// exceptions. We must translate each handle in the fd_set structures to
// their underlying provider handles before calling the next provider's
// WSPSelect.
//
int WSPAPI WSPSelect(
int nfds,
fd_set FAR * readfds,
fd_set FAR * writefds,
fd_set FAR * exceptfds,
const struct timeval FAR * timeout,
LPINT lpErrno)
{
SOCK_INFO *SocketContext=NULL;
u_int count,
i;
int HandleCount,
ret;
struct
{
SOCKET ClientSocket;
SOCKET ProvSocket;
} Read[FD_SETSIZE], Write[FD_SETSIZE], Except[FD_SETSIZE];
fd_set ReadFds, WriteFds, ExceptFds;
if ( !readfds && !writefds && !exceptfds )
{
*lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
//
// Translate all handles contained in the fd_set structures.
// For each fd_set go through and build another fd_set which contains
// their lower provider socket handles.
//
if (readfds)
{
FD_ZERO(&ReadFds);
if (readfds->fd_count > FD_SETSIZE)
{
*lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
for (i = 0; i < readfds->fd_count; i++)
{
SocketContext = FindAndLockSocketContext(
(Read[i].ClientSocket = readfds->fd_array[i]),
lpErrno
);
if (SocketContext == NULL)
{
dbgprint("WSPSelect(1): WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
Read[i].ProvSocket = SocketContext->ProviderSocket;
FD_SET(Read[i].ProvSocket, &ReadFds);
UnlockSocketContext(SocketContext, lpErrno);
}
}
if (writefds)
{
FD_ZERO(&WriteFds);
if (writefds->fd_count > FD_SETSIZE)
{
*lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
for (i = 0; i < writefds->fd_count; i++)
{
SocketContext = FindAndLockSocketContext(
(Write[i].ClientSocket = writefds->fd_array[i]),
lpErrno
);
if (SocketContext == NULL)
{
dbgprint("WSPSelect(2): WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
Write[i].ProvSocket = SocketContext->ProviderSocket;
FD_SET(Write[i].ProvSocket, &WriteFds);
UnlockSocketContext(SocketContext, lpErrno);
}
}
if (exceptfds)
{
FD_ZERO(&ExceptFds);
if (exceptfds->fd_count > FD_SETSIZE)
{
*lpErrno = WSAENOBUFS;
return SOCKET_ERROR;
}
for (i = 0; i < exceptfds->fd_count; i++)
{
SocketContext = FindAndLockSocketContext(
(Except[i].ClientSocket = exceptfds->fd_array[i]),
lpErrno
);
if (SocketContext == NULL)
{
dbgprint("WSPSelect(3): WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
Except[i].ProvSocket = SocketContext->ProviderSocket;
FD_SET(Except[i].ProvSocket, &ExceptFds);
UnlockSocketContext(SocketContext, lpErrno);
}
}
//
// Now call the lower provider's WSPSelect with the fd_set structures we built
// containing the lower provider's socket handles.
//
if (SocketContext == NULL)
{
*lpErrno = WSAEINVAL;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContex
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -