/* * @implemented */ INT WSAAPI WSADuplicateSocketA(IN SOCKET s, IN DWORD dwProcessId, OUT LPWSAPROTOCOL_INFOA lpProtocolInfo) { WSAPROTOCOL_INFOW ProtocolInfoW; INT ErrorCode; DPRINT("WSADuplicateSocketA: %lx, %lx, %p\n", s, dwProcessId, lpProtocolInfo); /* Call the Unicode Function */ ErrorCode = WSADuplicateSocketW(s, dwProcessId, &ProtocolInfoW); /* Check for success */ if (ErrorCode == ERROR_SUCCESS) { /* Convert Protocol Info to Ansi */ if (lpProtocolInfo) { /* Convert the information to ANSI */ ErrorCode = MapUnicodeProtocolInfoToAnsi(&ProtocolInfoW, lpProtocolInfo); } else { /* Fail */ ErrorCode = WSAEFAULT; } /* Check if the conversion failed */ if (ErrorCode != ERROR_SUCCESS) { /* Set the last error and normalize the error */ SetLastError(ErrorCode); ErrorCode = SOCKET_ERROR; } } /* Return */ return ErrorCode; }
/* * @implemented */ INT WSAAPI getsockopt(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; }