📄 spi.cpp
字号:
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPEnumNetworkEvents(
SocketContext->ProviderSocket,
hEventObject,
lpNetworkEvents,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPEventSelect
//
// Description:
// Register the specified events on the socket with the given event handle.
// All we need to do is translate the socket handle.
//
int WSPAPI WSPEventSelect(
SOCKET s,
WSAEVENT hEventObject,
long lNetworkEvents,
LPINT lpErrno)
{
SOCK_INFO *SocketContext;
INT ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPEventSelect: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPEventSelect(
SocketContext->ProviderSocket,
hEventObject,
lNetworkEvents,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPGetOverlappedResult
//
// Description:
// This function reports whether the specified overlapped call has
// completed. If it has, return the requested information. If not,
// and fWait is true, wait until completion. Otherwise return an
// error immediately.
//
BOOL WSPAPI WSPGetOverlappedResult (
SOCKET s,
LPWSAOVERLAPPED lpOverlapped,
LPDWORD lpcbTransfer,
BOOL fWait,
LPDWORD lpdwFlags,
LPINT lpErrno)
{
DWORD ret;
s;
if (lpOverlapped->Internal != WSS_OPERATION_IN_PROGRESS)
{
// Operation has completed, update the parameters and return
//
*lpcbTransfer = (DWORD)lpOverlapped->InternalHigh;
*lpdwFlags = (DWORD)lpOverlapped->OffsetHigh;
*lpErrno = (INT)lpOverlapped->Offset;
return (lpOverlapped->Offset == 0 ? TRUE : FALSE);
}
else
{
// Operation is still in progress
//
if (fWait)
{
// Wait on the app supplied event handle. Once the operation
// is completed the IOCP or completion routine will fire.
// Once that is handled, WPUCompleteOverlappedRequest will
// be called which will signal the app event.
//
ret = WaitForSingleObject(lpOverlapped->hEvent, INFINITE);
if ( (ret == WAIT_OBJECT_0) &&
(lpOverlapped->Internal != WSS_OPERATION_IN_PROGRESS) )
{
*lpcbTransfer = (DWORD)lpOverlapped->InternalHigh;
*lpdwFlags = (DWORD)lpOverlapped->OffsetHigh;
*lpErrno = (INT)lpOverlapped->Offset;
return(lpOverlapped->Offset == 0 ? TRUE : FALSE);
}
else if (lpOverlapped->Internal == WSS_OPERATION_IN_PROGRESS)
*lpErrno = WSA_IO_PENDING;
else
*lpErrno = WSASYSCALLFAILURE;
}
else
*lpErrno = WSA_IO_INCOMPLETE;
}
return FALSE;
}
//
// Function: WSPGetPeerName
//
// Description:
// Returns the address of the peer. The only thing we need to do is translate
// the socket handle.
//
int WSPAPI WSPGetPeerName(
SOCKET s,
struct sockaddr FAR * name,
LPINT namelen,
LPINT lpErrno)
{
SOCK_INFO *SocketContext;
INT ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPGetPeerName: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPGetPeerName(
SocketContext->ProviderSocket,
name,
namelen,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPGetSockName
//
// Description:
// Returns the local address of a socket. All we need to do is translate
// the socket handle.
//
int WSPAPI WSPGetSockName(
SOCKET s,
struct sockaddr FAR * name,
LPINT namelen,
LPINT lpErrno)
{
SOCK_INFO *SocketContext;
INT ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPGetSockName: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPGetSockName(
SocketContext->ProviderSocket,
name,
namelen,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPGetSockOpt
//
// Description:
// Get the specified socket option. All we need to do is translate the
// socket handle.
//
int WSPAPI WSPGetSockOpt(
SOCKET s,
int level,
int optname,
char FAR * optval,
LPINT optlen,
LPINT lpErrno)
{
SOCK_INFO *SocketContext;
INT ret=NO_ERROR;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPGetSockOpt: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
//
// We need to capture this and return our own WSAPROTOCOL_INFO structure.
// Otherwise, if we translate the handle and pass it to the lower provider
// we'll return the lower provider's protocol info!
//
if ((level == SOL_SOCKET) && ((optname == SO_PROTOCOL_INFO) ||
(optname == SO_PROTOCOL_INFOA) ||
(optname == SO_PROTOCOL_INFOW) ))
{
if ((optname == SO_PROTOCOL_INFOW) && (*optlen >= sizeof(WSAPROTOCOL_INFOW)))
{
// No conversion necessary, just copy the data
memcpy(optval,
&SocketContext->Provider->LayeredProvider,
sizeof(WSAPROTOCOL_INFOW));
}
else if ((optname == SO_PROTOCOL_INFOA) && (*optval >= sizeof(WSAPROTOCOL_INFOA)))
{
// Copy everything but the string
memcpy(optval,
&SocketContext->Provider->LayeredProvider,
sizeof(WSAPROTOCOL_INFOW)-WSAPROTOCOL_LEN+1);
// Convert our saved UNICODE string to ASCII
WideCharToMultiByte(CP_ACP,
0,
SocketContext->Provider->LayeredProvider.szProtocol,
-1,
((WSAPROTOCOL_INFOA *)optval)->szProtocol,
WSAPROTOCOL_LEN+1,
NULL,
NULL);
}
else
{
*lpErrno = WSAEFAULT;
ret = SOCKET_ERROR;
}
}
else
{
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPGetSockOpt(
SocketContext->ProviderSocket,
level,
optname,
optval,
optlen,
lpErrno);
SetBlockingProvider(NULL);
}
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPGetQOSByName
//
// Description:
// Get a QOS template by name. All we need to do is translate the socket
// handle.
//
BOOL WSPAPI WSPGetQOSByName(
SOCKET s,
LPWSABUF lpQOSName,
LPQOS lpQOS,
LPINT lpErrno)
{
SOCK_INFO *SocketContext;
INT ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPGetQOSByName: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPGetQOSByName(
SocketContext->ProviderSocket,
lpQOSName,
lpQOS,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPIoctl
//
// Description:
// Invoke an ioctl. In most cases, we just need to translate the socket
// handle. However, if the dwIoControlCode is SIO_GET_EXTENSION_FUNCTION_POINTER,
// we'll need to intercept this and return our own function pointers when
// they're requesting either TransmitFile or AcceptEx. This is necessary so
// we can trap these calls. Also for PnP OS's (Win2k) we need to trap calls
// to SIO_QUERY_TARGET_PNP_HANDLE. For this ioctl we simply have to return
// the provider socket.
//
int WSPAPI WSPIoctl(
SOCKET s,
DWORD dwIoControlCode,
LPVOID lpvInBuffer,
DWORD cbInBuffer,
LPVOID lpvOutBuffer,
DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno)
{
LPWSAOVERLAPPEDPLUS ProviderOverlapped=NULL;
SOCK_INFO *SocketContext;
GUID AcceptExGuid = WSAID_ACCEPTEX;
GUID TransmitFileGuid = WSAID_TRANSMITFILE;
GUID GetAcceptExSockAddrsGuid = WSAID_GETACCEPTEXSOCKADDRS;
GUID ConnectExGuid = WSAID_CONNECTEX;
GUID DisconnectExGuid = WSAID_DISCONNECTEX;
GUID TransmitPacketsGuid = WSAID_TRANSMITPACKETS;
GUID WSARecvMsgGuid = WSAID_WSARECVMSG;
int ret=NO_ERROR;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPIoctl: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
if (dwIoControlCode == SIO_GET_EXTENSION_FUNCTION_POINTER)
{
// Check to see which extension function is being requested.
//
if (memcmp (lpvInBuffer, &TransmitFileGuid, sizeof (GUID)) == 0)
{
// Return a pointer to our intermediate extesion function
//
*((LPFN_TRANSMITFILE *)lpvOutBuffer) = ExtTransmitFile;
//
// Attempt to load the lower provider's extension function
//
if (!SocketContext->Provider->NextProcTableExt.lpfnTransmitFile)
{
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPIoctl(
SocketContext->ProviderSocket,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&TransmitFileGuid,
sizeof(GUID),
(LPVOID) &SocketContext->Provider->NextProcTableExt.lpfnTransmitFile,
sizeof(LPFN_TRANSMITFILE),
lpcbBytesReturned,
NULL,
NULL,
NULL,
lpErrno);
SetBlockingProvider(NULL);
}
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
else if (memcmp(lpvInBuffer, &AcceptExGuid, sizeof(GUID)) == 0)
{
// Return a pointer to our intermediate extension function
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -