📄 spi.cpp
字号:
ret = SOCKET_ERROR;
if (IsWindow(hWnd))
{
// Verify only valid events have been set
//
if ( (lEvent & ~FD_ALL_EVENTS) == 0)
{
// Find our provider socket corresonding to this one
//
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext != NULL)
{
SocketContext->hWnd = hWnd;
SocketContext->uMsg = wMsg;
// Get the handle to our hidden window
//
if ((hWorkerWindow = GetWorkerWindow()) != NULL)
{
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPAsyncSelect(
SocketContext->ProviderSocket,
hWorkerWindow,
WM_SOCKET,
lEvent,
lpErrno);
SetBlockingProvider(NULL);
}
else
{
*lpErrno = WSAEINVAL;
}
UnlockSocketContext(SocketContext, lpErrno);
}
else
{
dbgprint("WSPAsyncSelect: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
}
}
else
{
*lpErrno = WSAEINVAL;
}
}
else
{
*lpErrno = WSAEINVAL;
}
return ret;
}
//
// Function: WSPBind
//
// Description:
// Bind the socket to a local address. We just map socket handles and
// call the lower provider.
//
int WSPAPI WSPBind(
SOCKET s,
const struct sockaddr FAR * name,
int namelen,
LPINT lpErrno)
{
SOCK_INFO *SocketContext;
INT ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPBind: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPBind(
SocketContext->ProviderSocket,
name,
namelen,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPCancelBlockingCall
//
// Description:
// This call cancels any blocking Winsock call in the current thread only.
// For every Winsock call that blocks we use thread local storage (TLS) to
// store a pointer to the provider on which the blocking call was issued.
// This is necessary since WSACancelBlockingCall takes no arguments (i.e.
// the LSP needs to keep track of what calls are blocking).
//
int WSPAPI WSPCancelBlockingCall(
LPINT lpErrno)
{
PROVIDER *Provider=NULL;
INT ret = NO_ERROR;
Provider = (PROVIDER *)TlsGetValue(TlsIndex);
if (!Provider)
{
ret = Provider->NextProcTable.lpWSPCancelBlockingCall(lpErrno);
}
return ret;
}
//
// Function: WSPCleanup
//
// Description:
// Decrement the entry count. If equal to zero then we can prepare to have us
// unloaded. Close any outstanding sockets and free up allocated memory.
//
int WSPAPI WSPCleanup(
LPINT lpErrno
)
{
int ret=NO_ERROR;
if (bDetached)
return NO_ERROR;
EnterCriticalSection(&gCriticalSection);
if (!gEntryCount)
{
*lpErrno = WSANOTINITIALISED;
dbgprint("WSPCleanup returning WSAENOTINITIALISED");
LeaveCriticalSection(&gCriticalSection);
return SOCKET_ERROR;
}
// Decrement the entry count
//
gEntryCount--;
dbgprint("WSPCleanup: %d", gEntryCount);
if (gEntryCount == 0)
{
dbgprint("WSPCleanup: gEntryCount == 0; cleaning up");
StopAsyncWindowManager();
StopOverlappedManager();
Sleep(200);
FreeSocketsAndMemory(lpErrno);
/*
DecrementLspUsage(hDllInstance, 1);
*/
}
LeaveCriticalSection(&gCriticalSection);
return ret;
}
//
// Function: WSPCloseSocket
//
// Description:
// Close the socket handle of the app socket as well as the provider socket.
// However, if there are outstanding async IO requests on the app socket
// we only close the provider socket. Only when all the IO requests complete
// (with error) will we then close the app socket (this will occur in
// the overlapped manager - overlapp.cpp).
//
int WSPAPI WSPCloseSocket(
SOCKET s,
LPINT lpErrno
)
{
SOCK_INFO *SocketContext;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPCloseSocket: WPUQuerySocketHandle() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
AcquireSocketLock(SocketContext);
dbgprint("WSPCloseSocket: Closing layered socket 0x%p (provider 0x%p)",
s, SocketContext->ProviderSocket);
//
// If we there are outstanding async calls on this handle don't close the app
// socket handle...only close the provider's handle. Therefore any errors
// incurred can be propogated back to the app socket.
//
if ((SocketContext->dwOutstandingAsync != 0) || (SocketContext->RefCount != 1))
{
SocketContext->bClosing = TRUE;
if (SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
SocketContext->ProviderSocket,
lpErrno) == SOCKET_ERROR)
{
*lpErrno = WSAENOTSOCK;
UnlockSocketContext(SocketContext, lpErrno);
dbgprint("WSPCloseSocket: Invalid socket handle");
return SOCKET_ERROR;
}
SocketContext->ProviderSocket = INVALID_SOCKET;
UnlockSocketContext(SocketContext, lpErrno);
return NO_ERROR;
}
//
// Close the provider socket
//
SetBlockingProvider(SocketContext->Provider);
if (SocketContext->Provider->NextProcTable.lpWSPCloseSocket(
SocketContext->ProviderSocket,
lpErrno) == SOCKET_ERROR)
{
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
dbgprint("WSPCloseSocket: Provider close failed");
return SOCKET_ERROR;
}
SetBlockingProvider(NULL);
SocketContext->ProviderSocket = INVALID_SOCKET;
//
// Remove the socket info
//
RemoveSocketInfo(SocketContext->Provider, SocketContext);
//
// Close the app socket
//
if (MainUpCallTable.lpWPUCloseSocketHandle(s, lpErrno) == SOCKET_ERROR)
{
dbgprint("WPUCloseSocketHandle failed: %d", *lpErrno);
ReleaseSocketLock(SocketContext);
return SOCKET_ERROR;
}
dbgprint("Closing socket %d Bytes Sent [%lu] Bytes Recv [%lu]",
s, SocketContext->BytesSent, SocketContext->BytesRecv);
ReleaseSocketLock(SocketContext);
DeleteCriticalSection(&SocketContext->SockCritSec);
HeapFree(hLspHeap, 0, SocketContext);
return NO_ERROR;
}
//
// Function: WSPConnect
//
// Description:
// Performs a connect call. The only thing we need to do is translate
// the socket handle.
//
int WSPAPI WSPConnect (
SOCKET s,
const struct sockaddr FAR * name,
int namelen,
LPWSABUF lpCallerData,
LPWSABUF lpCalleeData,
LPQOS lpSQOS,
LPQOS lpGQOS,
LPINT lpErrno
)
{
SOCK_INFO *SocketContext;
INT ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPConnect: WPUQuerySocketHandleContext() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPConnect(
SocketContext->ProviderSocket,
name,
namelen,
lpCallerData,
lpCalleeData,
lpSQOS,
lpGQOS,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
return ret;
}
//
// Function: WSPDuplicateSocket
//
// Description:
// This function provides a WSAPROTOCOL_INFOW structure which can be passed
// to another process to open a handle to the same socket. First we need
// to translate the user socket into the provider socket and call the underlying
// WSPDuplicateSocket. Note that the lpProtocolInfo structure passed into us
// is an out parameter only!
//
int WSPAPI WSPDuplicateSocket(
SOCKET s,
DWORD dwProcessId,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
LPINT lpErrno)
{
PROVIDER *Provider=NULL;
SOCK_INFO *SocketContext=NULL;
DWORD dwReserved;
int ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPDuplicateSocket: WPUQuerySocketHandle() failed: %d", *lpErrno);
*lpErrno = WSAENOTSOCK;
return SOCKET_ERROR;
}
//
// Find the underlying provider
//
Provider = SocketContext->Provider;
SetBlockingProvider(Provider);
ret = Provider->NextProcTable.lpWSPDuplicateSocket(
SocketContext->ProviderSocket,
dwProcessId,
lpProtocolInfo,
lpErrno);
SetBlockingProvider(NULL);
UnlockSocketContext(SocketContext, lpErrno);
if (ret == NO_ERROR)
{
// We want to return the WSAPROTOCOL_INFOW structure of the underlying
// provider but we need to preserve the reserved info returned by the
// WSPDuplicateSocket call.
//
dwReserved = lpProtocolInfo->dwProviderReserved;
memcpy(lpProtocolInfo, &Provider->LayeredProvider, sizeof(WSAPROTOCOL_INFOW));
lpProtocolInfo->dwProviderReserved = dwReserved;
}
return ret;
}
//
// Function: WSPEnumNetworkEvents
//
// Description:
// Enumerate the network events for a socket. We only need to translate the
// socket handle.
//
int WSPAPI WSPEnumNetworkEvents(
SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents,
LPINT lpErrno)
{
SOCK_INFO *SocketContext;
INT ret;
SocketContext = FindAndLockSocketContext(s, lpErrno);
if (SocketContext == NULL)
{
dbgprint("WSPEnumNetworkEvents: WPUQuerySocketHandleContext() failed: %d",
*lpErrno);
*lpErrno = WSAENOTSOCK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -