socket.c
来自「WinCE5.0部分核心源码」· C语言 代码 · 共 1,081 行 · 第 1/2 页
C
1,081 行
(TEXT("+WS2!WSASocket: %d, %d, %d ProtInfo %X Ret %u Err %u\r\n"),
af, type, protocol, lpProtocolInfo, hSock, Err));
return hSock;
} // WSASocket()
SOCKET SOCKAPI socket(
int af,
int type,
int protocol) {
SOCKET hSock;
// we may have to do some flag modifications...
hSock = WSASocket(af, type, protocol, NULL, 0, 0);
return hSock;
} // socket()
int WSAAPI closesocket(
IN SOCKET s) {
WsSocket *pSock;
int cRefs, Err = 0, Status = SOCKET_ERROR;
if (v_fProcessDetached) {
Err = WSAENETDOWN;
goto Exit;
}
CTEGetLock(&v_DllCS, 0);
if (Err = Started()) {
CTEFreeLock(&v_DllCS, 0);
goto Exit;
}
pSock = *_FindSocketHandle(s);
if (pSock && !(pSock->Flags & WS_SOCK_FL_CLOSED)) {
pSock->Flags |= WS_SOCK_FL_CLOSED;
CTEFreeLock(&v_DllCS, 0);
Status = pSock->pProvider->ProcTable.lpWSPCloseSocket(pSock->hWSPSock,
&Err);
if (Status) {
// this means the closesocket failed!
ASSERT(SOCKET_ERROR == Status);
pSock->Flags &= ~WS_SOCK_FL_CLOSED;
} else {
cRefs = DerefSocket(pSock);
ASSERT(cRefs >= 0);
}
} else {
CTEFreeLock(&v_DllCS, 0);
Err = WSAENOTSOCK;
}
Exit:
if (Err) {
SetLastError(Err);
}
return Status;
} // closesocket()
SOCKET WSAAPI WSAAccept (
SOCKET s,
struct sockaddr *addr,
LPINT addrlen,
LPCONDITIONPROC lpfnCondition,
DWORD_PTR dwCallbackData) {
int Err, cRefs;
WsSocket *pSock, *pNewSock;
SOCKET hSock;
if (! (Err = RefSocketHandle(s, &pSock))) {
// lower layers need to verify addr, addrlen, and other parameters
if (pNewSock = LocalAlloc(LPTR, sizeof(*pSock))) {
pNewSock->cRefs = 1;
// should increment provider ref before calling newsocket handle
CTEGetLock(&s_ProviderListLock, 0);
pSock->pProvider->cRefs++;
CTEFreeLock(&s_ProviderListLock, 0);
pNewSock->pProvider = pSock->pProvider;
CTEGetLock(&v_DllCS, 0);
hSock = NewSocketHandle(pNewSock);
CTEFreeLock(&v_DllCS, 0);
if (INVALID_SOCKET != hSock) {
pNewSock->hWSPSock = pSock->pProvider->ProcTable.
lpWSPAccept(pSock->hWSPSock, addr, addrlen,
lpfnCondition, dwCallbackData, &Err);
if (INVALID_SOCKET != pNewSock->hWSPSock) {
memcpy(&pNewSock->ProtInfo, &pSock->ProtInfo,
sizeof(pNewSock->ProtInfo));
// SUCCESS !!!
} else {
if ((INVALID_SOCKET == pNewSock->hWSPSock) && ! Err) {
ASSERT(0);
Err = WSASYSCALLFAILURE;
}
// oh oh, close and delete everything
pNewSock->Flags |= WS_SOCK_FL_CLOSED;
cRefs = DerefSocketHandle(pNewSock->hSock);
ASSERT(cRefs == 0);
}
} else {
LocalFree(pSock);
DerefProvider(&pSock->pProvider->Id, pSock->pProvider);
Err = WSAEMFILE;
}
} else
Err = WSA_NOT_ENOUGH_MEMORY;
DerefSocket(pSock);
} else
Err = WSAENOTSOCK;
if (Err) {
SetLastError(Err);
hSock = INVALID_SOCKET;
}
return hSock;
} // WSAAccept()
SOCKET WSAAPI accept (
SOCKET s,
struct sockaddr *addr,
int *addrlen) {
return WSAAccept(s, addr, addrlen, NULL, 0);
} // accept()
BOOL WSAAPI WSAGetOverlappedResult (
IN SOCKET s,
IN LPWSAOVERLAPPED lpOverlapped,
OUT LPDWORD lpcbTransfer,
IN BOOL fWait,
OUT LPDWORD lpdwFlags) {
int Err;
WsSocket *pSock;
BOOL Status; // note status is a bool and used differently
if (! lpOverlapped || ! lpcbTransfer || ! lpdwFlags) {
Err = WSAEFAULT;
} else if (! (Err = RefSocketHandle(s, &pSock))) {
Status = pSock->pProvider->ProcTable.lpWSPGetOverlappedResult(
pSock->hWSPSock, lpOverlapped, lpcbTransfer, fWait,
lpdwFlags, &Err);
if (!Status && !Err) {
ASSERT(0);
Err = WSASYSCALLFAILURE;
}
DerefSocket(pSock);
}
if (Err) {
SetLastError(Err);
Status = FALSE;
}
return Status;
} // WSAGetOverlappedResult()
int WPUCloseSocketHandle (
SOCKET s,
LPINT lpErrno) {
SOCKET hSock = INVALID_SOCKET;
WsSocket *pSock, **ppSock;
int Ret;
CTEGetLock(&v_DllCS, 0);
ppSock = _FindSocketHandle(s);
if (pSock = *ppSock) {
pSock->Flags |= WS_SOCK_FL_CLOSED;
DerefSocketHandle(pSock->hSock);
Ret = 0;
} else {
SetErrorCode(WSAENOTSOCK, lpErrno);
Ret = SOCKET_ERROR;
}
CTEFreeLock(&v_DllCS, 0);
return Ret;
} // WPUCloseSocketHandle
SOCKET WPUCreateSocketHandle(
DWORD dwCatalogEntryId,
DWORD dwContext,
LPINT lpErrno) {
SOCKET hSock = INVALID_SOCKET;
WsSocket *pSock;
int Err;
WCHAR sDllPath[MAX_PATH];
WSAPROTOCOL_INFOW ProtInfo;
WsProvider *pProv;
LPWSPSTARTUP pfnStartup;
WSPDATA WSPData;
WSPUPCALLTABLE UCTbl; // compiler
if (pSock = LocalAlloc(LPTR, sizeof(*pSock))) {
Err = PMFindProvider(0, 0, 0, dwCatalogEntryId, 1,
&ProtInfo, sDllPath);
if (! Err) {
if (pProv = FindProvider(&ProtInfo.ProviderId)) {
pProv->cRefs++;
} else {
// ok so I was in rush... we should really reuse the code
// in GetProvider...
DEBUGMSG(ZONE_MISC,
(TEXT("WPUCreateSocketHandle: loading provider from WPUCreateSocketHandle\r\n")));
if (pProv = LocalAlloc(LPTR, sizeof(*pProv))) {
pProv->pNext = s_pProviderList;
pProv->cRefs = 1;
pProv->Id = ProtInfo.ProviderId;
if (pProv->hLibrary = LoadLibrary(sDllPath)) {
pfnStartup = (LPWSPSTARTUP)GetProcAddress(pProv->hLibrary,
TEXT("WSPStartup"));
memcpy(&UCTbl, &UpCalls, sizeof(WSPUPCALLTABLE)); // compiler
if (!pfnStartup) {
Err = WSAEPROVIDERFAILEDINIT;
} else if (Err = (*pfnStartup) (WINSOCK_VERSION, &WSPData,
&ProtInfo, UCTbl, &pProv->ProcTable)) { // compiler
;
} else if (WSPData.wVersion != WINSOCK_VERSION) {
pProv->ProcTable.lpWSPCleanup(&Err);
ASSERT(0 == Err);
Err = WSAEINVALIDPROVIDER;
} else {
// Partial SUCCESS
s_pProviderList = pProv;
wcscpy(pProv->sDllPath, sDllPath);
}
} else
Err = WSAEPROVIDERFAILEDINIT;
if (Err) {
if (pProv->hLibrary)
CloseHandle(pProv->hLibrary);
LocalFree(pProv);
pProv = NULL;
}
} else
Err = WSAENOBUFS;
} // else (pProv = FindProvider(...)
CTEFreeLock(&s_ProviderListLock, 0);
}
if (!Err) {
pSock->cRefs = 1;
CTEGetLock(&v_DllCS, 0);
hSock = NewSocketHandle(pSock);
CTEFreeLock(&v_DllCS, 0);
if (INVALID_SOCKET != hSock) {
// Success!
pSock->pProvider = pProv;
// should we copy from ProtInfo or pProtInfo?
memcpy(&pSock->ProtInfo, &ProtInfo, sizeof(ProtInfo));
pSock->hWSPSock = (SOCKET)dwContext;
} else {
LocalFree(pSock);
DerefProvider(&ProtInfo.ProviderId, pProv);
Err = WSAEMFILE;
}
} else {
LocalFree(pSock);
}
} else {
Err = WSAENOBUFS;
}
if (Err) {
SetErrorCode(Err, lpErrno);
hSock = INVALID_SOCKET;
}
return hSock;
} // WPUCreateSocketHandle()
int WPUGetProviderPath(
LPGUID lpProviderId,
LPWSTR lpszProviderDllPath,
LPINT lpProviderDllPathLen,
LPINT lpErrno) {
WsProvider *pProv;
int Ret, Err = 0;
int cPathLen;
GUID myGuid;
myGuid = *lpProviderId; // so we don't crash holding CS
if (pProv = FindProvider(&myGuid)) {
__try {
cPathLen = wcslen(pProv->sDllPath);
if (cPathLen <= *lpProviderDllPathLen)
wcscpy(lpszProviderDllPath, pProv->sDllPath);
else
Err = WSAEFAULT;
*lpProviderDllPathLen = cPathLen;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Err = WSAEFAULT;
}
CTEFreeLock(&s_ProviderListLock, 0);
} else {
CTEFreeLock(&s_ProviderListLock, 0);
// we now need to query pm
{
WSAPROTOCOL_INFOW ProtInfo;
memset(&ProtInfo, 0, sizeof(ProtInfo));
memcpy(&ProtInfo, lpProviderId, sizeof(*lpProviderId));
Err = PMFindProvider(0, 0, 0, 0, 2, &ProtInfo,
lpszProviderDllPath);
if (! Err) {
__try {
*lpProviderDllPathLen = wcslen(lpszProviderDllPath);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Err = WSAEFAULT;
}
}
}
}
if (Err) {
SetErrorCode(Err, lpErrno);
Ret = SOCKET_ERROR;
} else {
Ret = 0;
}
return Ret;
} // WPUGetProviderPath()
int WPUQuerySocketHandleContext(
SOCKET s,
PDWORD_PTR lpContext,
LPINT lpErrno) {
WsSocket *pSock;
int Err;
CTEGetLock(&v_DllCS, 0);
// no longer check if Started, when we're processing WSACleanup we make
// calls to the providers which sometimes query the SocketHandle
// furthermore this isn't a user fn anyway--it is called by providers
// if (!(Err = Started())) {
Err = 0;
pSock = *_FindSocketHandle(s);
if (pSock) {
__try {
*lpContext = (DWORD)pSock->hWSPSock;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Err = WSAEFAULT;
}
} else
Err = WSAENOTSOCK;
CTEFreeLock(&v_DllCS, 0);
if (Err) {
SetErrorCode(Err, lpErrno);
Err = SOCKET_ERROR;
}
return Err;
} // WPUQuerySocketHandleContext()
int WPUCompleteOverlappedRequest(SOCKET s, LPWSAOVERLAPPED lpOverlapped,
DWORD dwError, DWORD cbTransferred, LPINT lpErrno) {
WsSocket *pSock, **ppSock;
int Ret;
// since we don't yet support completion ports this routine doesn't
// really do much other than set the values and signal the event
if (lpOverlapped) {
CTEGetLock(&v_DllCS, 0);
ppSock = _FindSocketHandle(s);
if (pSock = *ppSock) {
CTEFreeLock(&v_DllCS, 0);
lpOverlapped->InternalHigh = cbTransferred;
lpOverlapped->Internal = WSS_OPERATION_IN_PROGRESS + 1;
if (lpOverlapped->hEvent)
SetEvent(lpOverlapped->hEvent);
Ret = 0;
} else {
CTEFreeLock(&v_DllCS, 0);
Ret = WSAEINVAL;
}
} else {
Ret = WSA_INVALID_PARAMETER;
}
if (Ret) {
SetErrorCode(Ret, lpErrno);
Ret = SOCKET_ERROR;
}
return Ret;
} // WPUCompleteOverlappedRequest
void CloseAllSockets() {
WsSocket *pSock;
int i, Err = 0, Status = SOCKET_ERROR;
WsProvider *pProv;
LINGER Linger;
CTEGetLock(&v_DllCS, 0);
if (v_fClosingAll) {
goto Exit;
}
v_fClosingAll = TRUE;
for (i = 0; i < SOCK_HASH_SIZE; i++) {
while (pSock = v_apWsSocks[i]) {
v_apWsSocks[i] = pSock->pNext;
if (WS_SOCK_FL_CLOSED & pSock->Flags) {
DEBUGMSG(ZONE_WARN,
(TEXT("CloseAllSockets: Socket %X already closed\r\n"),
pSock));
continue;
}
pProv = pSock->pProvider;
pSock->Flags |= WS_SOCK_FL_CLOSED;
if (! v_fProcessDetached) {
if (pProv && pSock->hWSPSock) {
// abortively close the sockets
Linger.l_onoff = 1;
Linger.l_linger = 0;
Status = pProv->ProcTable.lpWSPSetSockOpt(
pSock->hWSPSock, SOL_SOCKET, SO_LINGER, (char *)&Linger,
sizeof(Linger), &Err);
if (Status) {
DEBUGMSG(ZONE_WARN,
(TEXT("CloseAllSockets: set Linger failed Sock %X Err: %d\r\n"),
pSock, Err));
}
Status = pProv->ProcTable.lpWSPCloseSocket(
pSock->hWSPSock, &Err);
if (Status) {
DEBUGMSG(ZONE_WARN,
(TEXT("CloseAllSockets: closesocket failed Sock %X Err: %d\r\n"),
pSock, Err));
}
}
} // ! v_fProcessDetached
--pSock->cRefs;
ASSERT(pSock->cRefs >= 0);
if (pSock->cRefs <= 0) {
pSock->pProvider = NULL;
LocalFree(pSock);
if (pProv) {
CTEFreeLock(&v_DllCS, 0);
DerefProvider(&pProv->Id, pProv);
CTEGetLock(&v_DllCS, 0);
}
}
}
}
v_fClosingAll = FALSE;
Exit:
CTEFreeLock(&v_DllCS, 0);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?