Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS WinSock 2 API * FILE: dll/win32/ws2_32/src/sockctrl.c * PURPOSE: Socket Control/State Support * PROGRAMMER: Alex Ionescu (alex@relsoft.net) */
/* INCLUDES ******************************************************************/
#include <ws2_32.h>
#define NDEBUG#include <debug.h>
/* FUNCTIONS *****************************************************************/
/* * @implemented */INTWSAAPIconnect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen){ PWSPROCESS Process; PWSTHREAD Thread; PWSSOCKET Socket; INT ErrorCode, OldErrorCode = ERROR_SUCCESS; INT Status; BOOLEAN TryAgain = TRUE; DPRINT("connect: %lx, %p, %lx\n", s, name, namelen);
/* Enter prolog */ ErrorCode = WsApiProlog(&Process, &Thread); if (ErrorCode == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { if (!IsBadReadPtr(name, sizeof(struct sockaddr))) { while (TRUE) { /* Make the call */ Status = Socket->Provider->Service.lpWSPConnect(s, name, namelen, NULL, NULL, NULL, NULL, &ErrorCode);
/* Check if error code was due to the host not being found */ if ((Status == SOCKET_ERROR) && ((ErrorCode == WSAEHOSTUNREACH) || (ErrorCode == WSAENETUNREACH))) { /* Check if we can try again */ if (TryAgain) { /* Save the old error code */ OldErrorCode = ErrorCode;
/* Make sure we don't retry 3 times */ TryAgain = FALSE;
/* Make the RAS Auto-dial attempt */ if (WSAttemptAutodialAddr(name, namelen)) continue; } else { /* Restore the error code */ ErrorCode = OldErrorCode; } }
/* Break out of the loop */ break; }
/* Deference the Socket Context */ WsSockDereference(Socket);
/* Return Provider Value */ if (Status == ERROR_SUCCESS) return Status;
/* If everything seemed fine, then the WSP call failed itself */ if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; } else { /* Invalid user pointer */ ErrorCode = WSAEFAULT; } } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* If this is Winsock 1.1, normalize the error code */ if ((ErrorCode == WSAEALREADY) && (LOBYTE(Process->Version) == 1)) { /* WS 1.1 apps expect this */ ErrorCode = WSAEINVAL; }
/* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR;}
/* * @implemented */INTWSAAPIlisten(IN SOCKET s, IN INT backlog){ PWSSOCKET Socket; INT Status; INT ErrorCode; DPRINT("connect: %lx, %lx\n", s, backlog);
/* Check for WSAStartup */ if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPListen(s, backlog, &ErrorCode); /* Deference the Socket Context */ WsSockDereference(Socket);
/* Return Provider Value */ if (Status == ERROR_SUCCESS) return Status;
/* If everything seemed fine, then the WSP call failed itself */ if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR;}
/* * @implemented */INTWSAAPIgetpeername(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR* namelen){ PWSSOCKET Socket; INT Status; INT ErrorCode; DPRINT("getpeername: %lx, %p, %lx\n", s, name, namelen);
/* Check for WSAStartup */ if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPGetPeerName(s, name, namelen, &ErrorCode); /* Deference the Socket Context */ WsSockDereference(Socket);
/* Return Provider Value */ if (Status == ERROR_SUCCESS) return Status;
/* If everything seemed fine, then the WSP call failed itself */ if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR;}
/* * @implemented */INTWSAAPIgetsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR* namelen){ PWSSOCKET Socket; INT Status; INT ErrorCode; DPRINT("getsockname: %lx, %p, %lx\n", s, name, namelen);
/* Check for WSAStartup */ if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { if (name && namelen && (*namelen >= sizeof(*name))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPGetSockName(s, name, namelen, &ErrorCode);
/* Deference the Socket Context */ WsSockDereference(Socket);
/* Return Provider Value */ if (Status == ERROR_SUCCESS) return Status;
/* If everything seemed fine, then the WSP call failed itself */ if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; } else { /* Deference the Socket Context */ WsSockDereference(Socket);
/* name or namelen not valid */ ErrorCode = WSAEFAULT; } } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR;}
/* * @implemented */INTWSAAPIgetsockopt(IN SOCKET s, IN INT level, IN INT optname, OUT CHAR FAR* optval, IN OUT INT FAR* optlen){ PWSPROCESS Process; PWSTHREAD Thread; PWSSOCKET Socket; INT ErrorCode; INT Status; WSAPROTOCOL_INFOW ProtocolInfo; PCHAR OldOptVal = NULL; INT OldOptLen = 0; DPRINT("getsockopt: %lx, %lx, %lx\n", s, level, optname);
/* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) { /* Check if we're getting the open type */ if ((level == SOL_SOCKET) && (optname == SO_OPENTYPE)) { /* Validate size */ Status = ERROR_SUCCESS; _SEH2_TRY { if (!(optlen) || (*optlen < sizeof(DWORD))) { /* Fail */ Status = SOCKET_ERROR; SetLastError(WSAEFAULT); _SEH2_LEAVE; }
/* Set the open type */ *(DWORD*)optval = Thread->OpenType; *optlen = sizeof(DWORD); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = SOCKET_ERROR; SetLastError(WSAEFAULT); } _SEH2_END;
return Status; }
/* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Check if ANSI data was requested */ if ((level == SOL_SOCKET) && (optname == SO_PROTOCOL_INFOA)) { /* Validate size and pointers */ ErrorCode = NO_ERROR; _SEH2_TRY { if (!(optval) || !(optlen) || (*optlen < sizeof(WSAPROTOCOL_INFOA))) { /* Set return size and error code */ *optlen = sizeof(WSAPROTOCOL_INFOA); ErrorCode = WSAEFAULT; _SEH2_LEAVE; }
/* It worked. Save the values */ OldOptLen = *optlen; OldOptVal = optval;
/* Hack them so WSP will know how to deal with it */ *optlen = sizeof(WSAPROTOCOL_INFOW); optval = (PCHAR)&ProtocolInfo; optname = SO_PROTOCOL_INFOW; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ErrorCode = WSAEFAULT; } _SEH2_END;
/* Did we encounter invalid parameters? */ if (ErrorCode != NO_ERROR) { /* Dereference the socket and fail */ WsSockDereference(Socket); SetLastError(ErrorCode); return SOCKET_ERROR; } }
/* Make the call */ Status = Socket->Provider->Service.lpWSPGetSockOpt(s, level, optname, optval, optlen, &ErrorCode);
/* Deference the Socket Context */ WsSockDereference(Socket);
/* Check provider value */ if (Status == ERROR_SUCCESS) { /* Did we use the A->W hack? */ if (!OldOptVal) return Status;
/* We did, so we have to convert the unicode info to ansi */ ErrorCode = MapUnicodeProtocolInfoToAnsi(&ProtocolInfo, (LPWSAPROTOCOL_INFOA) OldOptVal);
/* Return the length */ _SEH2_TRY { *optlen = OldOptLen; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ErrorCode = WSAEFAULT; } _SEH2_END;
/* Return success if this worked */ if (ErrorCode == ERROR_SUCCESS) return Status; }
/* If everything seemed fine, then the WSP call failed itself */ if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR;}
/* * @implemented */INTWSAAPIsetsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR* optval, IN INT optlen){ PWSPROCESS Process; PWSTHREAD Thread; PWSSOCKET Socket; INT ErrorCode; INT Status; DPRINT("setsockopt: %lx, %lx, %lx\n", s, level, optname);
/* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) { /* Check if we're changing the open type */ if (level == SOL_SOCKET && optname == SO_OPENTYPE) { /* Validate size */ if (optlen < sizeof(DWORD)) { /* Fail */ SetLastError(WSAEFAULT); return SOCKET_ERROR; }
/* Set the open type */ Status = ERROR_SUCCESS; _SEH2_TRY { Thread->OpenType = *(DWORD*)optval; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = SOCKET_ERROR; SetLastError(WSAEFAULT); } _SEH2_END;
return Status; } if (!optval && optlen > 0) { SetLastError(WSAEFAULT); return SOCKET_ERROR; }
/* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPSetSockOpt(s, level, optname, optval, optlen, &ErrorCode);
/* Deference the Socket Context */ WsSockDereference(Socket);
/* Return Provider Value */ if (Status == ERROR_SUCCESS) return Status;
/* If everything seemed fine, then the WSP call failed itself */ if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR;}
/* * @implemented */INTWSAAPIshutdown(IN SOCKET s, IN INT how){ PWSSOCKET Socket; INT Status; INT ErrorCode; DPRINT("shutdown: %lx, %lx\n", s, how);
/* Check for WSAStartup */ if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPShutdown(s, how, &ErrorCode);
/* Deference the Socket Context */ WsSockDereference(Socket);
/* Return Provider Value */ if (Status == ERROR_SUCCESS) return Status;
/* If everything seemed fine, then the WSP call failed itself */ if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR;}
/* * @implemented */INTWSAAPIWSAConnect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen, IN LPWSABUF lpCallerData, OUT LPWSABUF lpCalleeData, IN LPQOS lpSQOS, IN LPQOS lpGQOS){ PWSSOCKET Socket; INT Status; INT ErrorCode; DPRINT("WSAConnect: %lx, %lx, %lx, %p\n", s, name, namelen, lpCallerData);
/* Check for WSAStartup */ if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, &ErrorCode); /* Deference the Socket Context */ WsSockDereference(Socket);
/* Return Provider Value */ if (Status == ERROR_SUCCESS) return Status;
/* If everything seemed fine, then the WSP call failed itself */ if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR;}
/* * @implemented */BOOLWSAAPIWSAGetOverlappedResult(IN SOCKET s, IN LPWSAOVERLAPPED lpOverlapped, OUT LPDWORD lpcbTransfer, IN BOOL fWait, OUT LPDWORD lpdwFlags){ PWSSOCKET Socket; INT Status; INT ErrorCode; DPRINT("WSAGetOverlappedResult: %lx, %lx\n", s, lpOverlapped);
/* Check for WSAStartup */ if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPGetOverlappedResult(s, lpOverlapped, lpcbTransfer, fWait, lpdwFlags, &ErrorCode); /* Deference the Socket Context */ WsSockDereference(Socket);
/* Return Provider Value */ if (Status) return Status; } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } }
/* Return with an Error */ SetLastError(ErrorCode); return FALSE;}