/* * @implemented */ SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol) { PWSPROCESS Process; PWSTHREAD Thread; DWORD Flags = 0; INT ErrorCode; DPRINT("socket: %lx, %lx, %lx\n", af, type, protocol); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Fail here */ SetLastError(ErrorCode); return INVALID_SOCKET; } /* Check the current open type and use overlapped if it's default */ if (!Thread->OpenType) Flags = WSA_FLAG_OVERLAPPED; /* Make the protocol negative if this is NETBIOS */ if ((af == AF_NETBIOS) && (protocol > 0)) protocol *= -1; /* Now let WSA handle it */ return WSASocketW(af, type, protocol, NULL, 0, Flags); }
/* * @implemented */ HANDLE WSAAPI WSAAsyncGetProtoByName(IN HWND hWnd, IN UINT wMsg, IN CONST CHAR FAR *Name, OUT CHAR FAR *Buffer, IN INT BufferLength) { HANDLE TaskHandle; PWSPROCESS Process; PWSTHREAD Thread; PWSASYNCBLOCK AsyncBlock; INT ErrorCode; PVOID NameCopy; DPRINT("WSAAsyncGetProtoByName: %lx, %lx, %s\n", hWnd, wMsg, Name); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return NULL; } /* Initialize the Async Thread */ if (!WsAsyncCheckAndInitThread()) { /* Fail */ SetLastError(WSAENOBUFS); return NULL; } /* Allocate an async block */ if (!(AsyncBlock = WsAsyncAllocateBlock(strlen(Name) + sizeof(CHAR)))) { /* Fail */ SetLastError(WSAENOBUFS); return NULL; } /* Make a copy of the address */ NameCopy = AsyncBlock + 1; strcpy(NameCopy, Name); /* Initialize the Async Block */ AsyncBlock->Operation = WsAsyncGetProtoByName; AsyncBlock->GetProto.hWnd = hWnd; AsyncBlock->GetProto.wMsg = wMsg; AsyncBlock->GetProto.ByWhat = NameCopy; AsyncBlock->GetProto.Buffer = Buffer; AsyncBlock->GetProto.BufferLength = BufferLength; /* Save the task handle and queue the request */ TaskHandle = AsyncBlock->TaskHandle; WsAsyncQueueRequest(AsyncBlock); /* Return the task handle */ return TaskHandle; }
/* * @implemented */ HANDLE WSAAPI WSAAsyncGetServByPort(IN HWND hWnd, IN UINT wMsg, IN INT Port, IN CONST CHAR FAR *Protocol, OUT CHAR FAR *Buffer, IN INT BufferLength) { HANDLE TaskHandle; PWSPROCESS Process; PWSTHREAD Thread; PWSASYNCBLOCK AsyncBlock; INT ErrorCode; DPRINT("WSAAsyncGetProtoByNumber: %lx, %lx, %lx\n", hWnd, wMsg, Port); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return NULL; } /* Initialize the Async Thread */ if (!WsAsyncCheckAndInitThread()) { /* Fail */ SetLastError(WSAENOBUFS); return NULL; } /* Allocate an async block */ if (!(AsyncBlock = WsAsyncAllocateBlock(0))) { /* Fail */ SetLastError(WSAENOBUFS); return NULL; } /* Initialize the Async Block */ AsyncBlock->Operation = WsAsyncGetServByPort; AsyncBlock->GetServ.hWnd = hWnd; AsyncBlock->GetServ.wMsg = wMsg; AsyncBlock->GetServ.ByWhat = UlongToPtr(Port); AsyncBlock->GetServ.Protocol = (PCHAR)Protocol; AsyncBlock->GetServ.Buffer = Buffer; AsyncBlock->GetServ.BufferLength = BufferLength; /* Save the task handle and queue the request */ TaskHandle = AsyncBlock->TaskHandle; WsAsyncQueueRequest(AsyncBlock); /* Return the task handle */ return TaskHandle; }
INT WSAAPI WsSlowProlog(VOID) { PWSPROCESS Process; PWSTHREAD Thread; /* Call the prolog */ return WsApiProlog(&Process, &Thread); }
/* * @implemented */ INT WSAAPI WSACleanup(VOID) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; LONG RefCount; DPRINT("WSACleanup\n"); /* Enter startup lock */ WsStartupLock(); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) { /* Decrement process reference count and check if it's zero */ if (!(RefCount = InterlockedDecrement(&Process->RefCount))) { /* It's zero, destroy the process structure */ WsProcDelete(Process); } else if (RefCount == 1 && WsAsyncThreadInitialized) { /* Kill async thread */ WsAsyncTerminateThread(); } /* Return success */ ErrorCode = ERROR_SUCCESS; } else { /* Weren't initialized */ SetLastError(ErrorCode); ErrorCode = SOCKET_ERROR; } /* Release startup lock */ WsStartupUnlock(); /* Done */ return ErrorCode; }
/* * @implemented */ INT WSAAPI WSASendDisconnect(IN SOCKET s, IN LPWSABUF lpOutboundDisconnectData) { PWSPROCESS Process; PWSTHREAD Thread; PWSSOCKET Socket; INT ErrorCode; INT Status; DPRINT("WSASendDisconnect: %lx %p\n", s, lpOutboundDisconnectData); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPSendDisconnect(s, lpOutboundDisconnectData, &ErrorCode); /* Deference the Socket Context */ WsSockDereference(Socket); /* Return Provider Value */ if (Status == ERROR_SUCCESS) return ERROR_SUCCESS; /* 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 */ INT WINAPI WSALookupServiceNextW(IN HANDLE hLookup, IN DWORD dwControlFlags, IN OUT LPDWORD lpdwBufferLength, OUT LPWSAQUERYSETW lpqsResults) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; PNSQUERY Query = hLookup; DPRINT("WSALookupServiceNextW: %lx\n", hLookup); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return SOCKET_ERROR; } /* Check for a valid handle, then validate and reference it */ if (!(Query) || !(WsNqValidateAndReference(Query))) { /* Fail */ SetLastError(WSA_INVALID_HANDLE); return SOCKET_ERROR; } /* Do the lookup */ ErrorCode = WsNqLookupServiceNext(Query, dwControlFlags, lpdwBufferLength, lpqsResults); /* Remove the validation reference */ WsNqDereference(Query); /* Return */ return ErrorCode; }
INT WSAAPI WsSlowPrologTid(OUT LPWSATHREADID *ThreadId) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; /* Call the prolog */ ErrorCode = WsApiProlog(&Process, &Thread); /* Check for success */ if (ErrorCode == ERROR_SUCCESS) { /* Return the Thread ID */ *ThreadId = &Thread->WahThreadId; } /* Return status */ return ErrorCode; }
/* * @implemented */ INT WSAAPI WSARecvDisconnect(IN SOCKET s, OUT LPWSABUF lpInboundDisconnectData) { PWSPROCESS Process; PWSTHREAD Thread; PWSSOCKET Socket; INT ErrorCode; INT Status; DPRINT("WSARecvDisconnect: %lx %p\n", s, lpInboundDisconnectData); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Make the call */ Status = Socket->Provider->Service.lpWSPRecvDisconnect(s, lpInboundDisconnectData, &ErrorCode); /* Deference the Socket Context */ WsSockDereference(Socket); /* Return Provider Value */ if (Status == ERROR_SUCCESS) return ERROR_SUCCESS; } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } } /* Return with an Error */ SetLastError(ErrorCode); return SOCKET_ERROR; }
/* * @implemented */ INT WSAAPI WSALookupServiceEnd(IN HANDLE hLookup) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; PNSQUERY Query = hLookup; DPRINT("WSALookupServiceEnd: %lx\n", hLookup); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return SOCKET_ERROR; } /* Check for a valid handle, then validate and reference it */ if (!(Query) || !(WsNqValidateAndReference(Query))) { /* Fail */ SetLastError(WSA_INVALID_HANDLE); return SOCKET_ERROR; } /* Do the lookup */ ErrorCode = WsNqLookupServiceEnd(Query); /* Remove the validation reference */ WsNqDereference(Query); /* Remove the keep-alive */ WsNqDereference(Query); /* Return */ return ERROR_SUCCESS; }
/* * @implemented */ INT WSAAPI WSACancelAsyncRequest(IN HANDLE hAsyncTaskHandle) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; DPRINT("WSACancelAsyncRequest: %lx\n", hAsyncTaskHandle); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) { /* Call the Async code */ ErrorCode = WsAsyncCancelRequest(hAsyncTaskHandle); /* Return */ if (ErrorCode == ERROR_SUCCESS) return ERROR_SUCCESS; } /* Fail */ SetLastError(ErrorCode); return SOCKET_ERROR; }
/* * @implemented */ PHOSTENT WSAAPI gethostbyaddr(IN const char FAR * addr, IN int len, IN int type) { CHAR AddressBuffer[100]; PHOSTENT Hostent; LPBLOB Blob; CHAR ResultsBuffer[RNR_BUFFER_SIZE]; PCHAR Results = ResultsBuffer; PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; DPRINT("gethostbyaddr: %s\n", addr); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return NULL; } /* Check for valid address pointer */ if (!addr) { /* Fail */ SetLastError(WSAEINVAL); return NULL; } /* Check which type it is */ if (type == AF_INET) { /* Use IPV4 Address to String */ Local_Ip4AddresstoString(AddressBuffer, (PCHAR)addr); } else if (type == AF_INET6) { /* Use IPV6 Address to String */ Local_Ip6AddresstoString(AddressBuffer, (PCHAR)addr); } else { /* Invalid address type; fail */ SetLastError(WSAEINVAL); return NULL; } /* Get the Hostname in a Blob Structure */ Blob = getxyDataEnt(&Results, RNR_BUFFER_SIZE, AddressBuffer, &AddressGuid, 0); /* Check if we got a blob */ if(Blob) { /* Copy the blob to our buffer and convert it */ Hostent = WsThreadBlobToHostent(Thread, Blob); /* Unpack the hostent */ if(Hostent) UnpackHostEnt(Hostent); } else { /* We failed, so zero it out */ Hostent = 0; /* Normalize the error message */ if(GetLastError() == WSASERVICE_NOT_FOUND) { SetLastError(WSAHOST_NOT_FOUND); } } /* Check if we received a newly allocated buffer; free it. */ if (Results != ResultsBuffer) HeapFree(WsSockHeap, 0, Results); /* Return the hostent */ return Hostent; }
/* * @implemented */ INT WINAPI WSALookupServiceBeginW(IN LPWSAQUERYSETW lpqsRestrictions, IN DWORD dwControlFlags, OUT LPHANDLE lphLookup) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; PNSQUERY Query; DPRINT("WSALookupServiceBeginW: %p\n", lpqsRestrictions); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return SOCKET_ERROR; } /* Verify pointers */ if (IsBadWritePtr(lphLookup, sizeof(*lphLookup)) || IsBadReadPtr(lpqsRestrictions, sizeof(*lpqsRestrictions))) { /* They are invalid; fail */ SetLastError(WSAEFAULT); return SOCKET_ERROR; } /* Create a new query object */ if ((Query = WsNqAllocate())) { /* Initialize it */ WsNqInitialize(Query); /* Do the lookup */ ErrorCode = WsNqLookupServiceBegin(Query, lpqsRestrictions, dwControlFlags, WsProcGetNsCatalog(Process)); /* Check for success */ if (ErrorCode == ERROR_SUCCESS) { /* Return the handle */ *lphLookup = Query; } else { /* Fail */ *lphLookup = NULL; WsNqDelete(Query); } } else { /* No memory */ ErrorCode = SOCKET_ERROR; SetLastError(WSAENOBUFS); } /* 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; }
/* * @implemented */ INT WSAAPI connect(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))) { 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 { /* 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; }
WSAAPI inet_ntoa(IN IN_ADDR in) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; WSADATA WsaData; BOOL ManualLoad = FALSE; CHAR b[10]; PCHAR p; DPRINT("inet_ntoa: %lx\n", in); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { DPRINT("MANUAL LOAD\n"); /* Only fail if the error wasn't related to a missing WSAStartup */ if (ErrorCode != WSANOTINITIALISED) { /* Fail */ SetLastError(ErrorCode); return NULL; } /* Apps aren't expected to call WSAStartup for this API, so we will */ if ((ErrorCode = WSAStartup(MAKEWORD(2,2), &WsaData)) != ERROR_SUCCESS) { /* We failed */ SetLastError(ErrorCode); return NULL; } /* Try the prolog again */ ManualLoad = TRUE; if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Failed again... */ WSACleanup(); SetLastError(ErrorCode); return NULL; } } p = Thread->Buffer; _itoa(in.S_un.S_addr & 0xFF, b, 10); strcpy(p, b); _itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10); strcat(p, "."); strcat(p, b); _itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10); strcat(p, "."); strcat(p, b); _itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10); strcat(p, "."); strcat(p, b); /* Cleanup the manual load */ if (ManualLoad) WSACleanup(); /* Return the buffer */ return p; }
/* * @implemented */ SOCKET WSAAPI WSAAccept(IN SOCKET s, OUT LPSOCKADDR addr, IN OUT LPINT addrlen, IN LPCONDITIONPROC lpfnCondition, IN DWORD_PTR dwCallbackData) { PWSPROCESS Process; PWSTHREAD Thread; PWSSOCKET Socket; DWORD OpenType; INT ErrorCode; SOCKET Status; DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s, addr, addrlen, lpfnCondition); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Get the old open type and set new one */ OpenType = Thread->OpenType; Thread->OpenType = Socket->Overlapped ? 0 : SO_SYNCHRONOUS_NONALERT; /* Make the call */ Status = Socket->Provider->Service.lpWSPAccept(s, addr, addrlen, lpfnCondition, dwCallbackData, &ErrorCode); /* Restore open type */ Thread->OpenType = OpenType; /* Deference the Socket Context */ WsSockDereference(Socket); /* Check if we got a valid socket */ if (Status != INVALID_SOCKET) { /* Check if we got a new socket */ if (Status != s) { /* Add a new reference */ WsSockAddApiReference(Status); } /* Return */ return Status; } } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } } /* Return with an Error */ SetLastError(ErrorCode); return INVALID_SOCKET; }
/* * @implemented */ SOCKET WSAAPI WSAJoinLeaf(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen, IN LPWSABUF lpCallerData, OUT LPWSABUF lpCalleeData, IN LPQOS lpSQOS, IN LPQOS lpGQOS, IN DWORD dwFlags) { PWSPROCESS Process; PWSTHREAD Thread; PWSSOCKET Socket; DWORD OpenType; INT ErrorCode; SOCKET Status; DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s, name, namelen); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) { /* Get the Socket Context */ if ((Socket = WsSockGetSocket(s))) { /* Get the old open type and set new one */ OpenType = Thread->OpenType; Thread->OpenType = Socket->Overlapped ? 0 : SO_SYNCHRONOUS_NONALERT; /* Make the call */ Status = Socket->Provider->Service.lpWSPJoinLeaf(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, dwFlags, &ErrorCode); /* Restore open type */ Thread->OpenType = OpenType; /* Deference the Socket Context */ WsSockDereference(Socket); /* Check if we got a valid socket */ if (Status != INVALID_SOCKET) { /* Check if we got a new socket */ if (Status != s) { /* Add a new reference */ WsSockAddApiReference(Status); } /* Return */ return Status; } } else { /* No Socket Context Found */ ErrorCode = WSAENOTSOCK; } } /* Return with an Error */ SetLastError(ErrorCode); return INVALID_SOCKET; }
/* * @implemented */ HANDLE WSAAPI WSAAsyncGetHostByAddr(IN HWND hWnd, IN UINT wMsg, IN CONST CHAR FAR *Address, IN INT Length, IN INT Type, OUT CHAR FAR *Buffer, IN INT BufferLength) { HANDLE TaskHandle; PWSPROCESS Process; PWSTHREAD Thread; PVOID AddressCopy; PWSASYNCBLOCK AsyncBlock; INT ErrorCode; DPRINT("WSAAsyncGetHostByAddr: %lx, %lx, %s\n", hWnd, wMsg, Address); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return NULL; } /* Initialize the Async Thread */ if (!WsAsyncCheckAndInitThread()) { /* Fail */ SetLastError(WSAENOBUFS); return NULL; } /* Allocate an async block */ if (!(AsyncBlock = WsAsyncAllocateBlock(Length))) { /* Fail */ SetLastError(WSAENOBUFS); return NULL; } /* Make a copy of the address */ AddressCopy = AsyncBlock + 1; RtlMoveMemory(AddressCopy, Address, Length); /* Initialize the Async Block */ AsyncBlock->Operation = WsAsyncGetHostByAddr; AsyncBlock->GetHost.hWnd = hWnd; AsyncBlock->GetHost.wMsg = wMsg; AsyncBlock->GetHost.ByWhat = AddressCopy; AsyncBlock->GetHost.Length = Length; AsyncBlock->GetHost.Type = Type; AsyncBlock->GetHost.Buffer = Buffer; AsyncBlock->GetHost.BufferLength = BufferLength; /* Save the task handle and queue the request */ TaskHandle = AsyncBlock->TaskHandle; WsAsyncQueueRequest(AsyncBlock); /* Return the task handle */ return TaskHandle; }
/* * @implemented */ INT WSAAPI WSAStringToAddressA(IN LPSTR AddressString, IN INT AddressFamily, IN LPWSAPROTOCOL_INFOA lpProtocolInfo, OUT LPSOCKADDR lpAddress, IN OUT LPINT lpAddressLength) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode, Status; DWORD CatalogEntryId; PTCATALOG Catalog; PTCATALOG_ENTRY CatalogEntry; LPWSTR UnicodeString; DWORD Length = (DWORD)strlen(AddressString) + 1; DPRINT("WSAStringToAddressA: %s\n", AddressString); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return SOCKET_ERROR; } /* Allocate the unicode string */ UnicodeString = HeapAlloc(WsSockHeap, 0, Length * 2); if (!UnicodeString) { /* No memory; fail */ SetLastError(WSAENOBUFS); return SOCKET_ERROR; } /* Convert the string */ MultiByteToWideChar(CP_ACP, 0, AddressString, -1, UnicodeString, Length); /* Get the catalog */ Catalog = WsProcGetTCatalog(Process); /* Check if we got custom protocol info */ if (lpProtocolInfo) { /* Get the entry ID */ CatalogEntryId = lpProtocolInfo->dwCatalogEntryId; /* Get the entry associated with it */ ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog, CatalogEntryId, &CatalogEntry); } else { /* Get it from the address family */ ErrorCode = WsTcGetEntryFromAf(Catalog, AddressFamily, &CatalogEntry); } /* Check for success */ if (ErrorCode == ERROR_SUCCESS) { /* Call the provider */ Status = CatalogEntry->Provider->Service.lpWSPStringToAddress(UnicodeString, AddressFamily, &CatalogEntry-> ProtocolInfo, lpAddress, lpAddressLength, &ErrorCode); /* Dereference the entry */ WsTcEntryDereference(CatalogEntry); /* Free the unicode string */ HeapFree(WsSockHeap, 0, UnicodeString); /* Check for success and return */ if (Status == ERROR_SUCCESS) return ERROR_SUCCESS; } else { /* Free the unicode string */ HeapFree(WsSockHeap, 0, UnicodeString); } /* Set the error and return */ SetLastError(ErrorCode); return SOCKET_ERROR; }
/* * @implemented */ PHOSTENT WSAAPI gethostbyname(IN const char FAR * name) { PHOSTENT Hostent; LPBLOB Blob; INT ErrorCode; CHAR ResultsBuffer[RNR_BUFFER_SIZE]; PCHAR Results = ResultsBuffer; CHAR szLocalName[200]; PCHAR pszName; PWSPROCESS Process; PWSTHREAD Thread; DPRINT("gethostbyname: %s\n", name); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return NULL; } /* Check if no name was given */ if(!name || !*name) { /* This means we should do a local lookup first */ if(gethostname(szLocalName, 200) != NO_ERROR) return(NULL); pszName = szLocalName; } else { /* Use the name tha twas given to us */ pszName = (PCHAR)name; } /* Get the Hostname in a Blob Structure */ Blob = getxyDataEnt(&Results, RNR_BUFFER_SIZE, pszName, &HostAddrByNameGuid, 0); /* Check if we didn't get a blob, or if we got an empty name */ if (!(Blob) && (!(name) || !(*name))) { /* Try a new query */ Blob = getxyDataEnt(&Results, RNR_BUFFER_SIZE, NULL, &HostAddrByNameGuid, 0); } /* Check if we got a blob */ if(Blob) { /* Copy the blob to our buffer and convert it */ Hostent = WsThreadBlobToHostent(Thread, Blob); /* Unpack the hostent */ if(Hostent) UnpackHostEnt(Hostent); } else { /* We failed, so zero it out */ Hostent = 0; /* Normalize the error message */ if(GetLastError() == WSASERVICE_NOT_FOUND) { SetLastError(WSAHOST_NOT_FOUND); } } /* Check if we received a newly allocated buffer; free it. */ if (Results != ResultsBuffer) HeapFree(WsSockHeap, 0, Results); /* Notify RAS Auto-dial helper */ if (Hostent) WSNoteSuccessfulHostentLookup(name, *Hostent->h_addr); /* Return the hostent */ return Hostent; }
/* * @implemented */ SOCKET WSAAPI WSASocketW(IN INT af, IN INT type, IN INT protocol, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, IN GROUP g, IN DWORD dwFlags) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; PTCATALOG Catalog; DWORD CatalogId; PTCATALOG_ENTRY CatalogEntry; LPWSAPROTOCOL_INFOW ProtocolInfo; DWORD OpenType; SOCKET Status = INVALID_SOCKET; DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af, type, protocol, lpProtocolInfo); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Fail now */ SetLastError(ErrorCode); return INVALID_SOCKET; } /* Get the catalog */ Catalog = WsProcGetTCatalog(Process); /* Find a Provider for the Catalog ID */ if (lpProtocolInfo) { /* Get the catalog ID */ CatalogId = lpProtocolInfo->dwCatalogEntryId; /* Get the Catalog Entry */ ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog, CatalogId, &CatalogEntry); } else { /* No ID */ CatalogId = 0; DoLookup: /* Get the Catalog Data from the Socket Info */ ErrorCode = WsTcGetEntryFromTriplet(Catalog, af, type, protocol, CatalogId, &CatalogEntry); } /* Check for Success */ if (ErrorCode == ERROR_SUCCESS) { /* Use the default Protocol Info if none given */ ProtocolInfo = lpProtocolInfo ? lpProtocolInfo : &CatalogEntry->ProtocolInfo; /* Save the open type and set new one */ OpenType = Thread->OpenType; Thread->OpenType = (dwFlags & WSA_FLAG_OVERLAPPED) ? 0 : SO_SYNCHRONOUS_NONALERT; /* Call the Provider to create the Socket */ Status = CatalogEntry->Provider->Service.lpWSPSocket(af, type, protocol, ProtocolInfo, g, dwFlags, &ErrorCode); /* Restore open type */ Thread->OpenType = OpenType; /* Get the catalog ID now, and dereference */ CatalogId = ProtocolInfo->dwCatalogEntryId; WsTcEntryDereference(CatalogEntry); /* Did we fail with WSAEINPROGRESS and had no specific provider? */ if ((Status == INVALID_SOCKET) && (ErrorCode == WSAEINPROGRESS) && !(lpProtocolInfo)) { /* In that case, restart the lookup from this ID */ goto DoLookup; } /* Check if we got a valid socket */ if (Status != INVALID_SOCKET) { /* Add an API reference and return */ WsSockAddApiReference(Status); return Status; } } /* Return with an Error */ SetLastError(ErrorCode); return INVALID_SOCKET; }
/* * @implemented */ INT WSAAPI setsockopt(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(INT)) { /* Fail */ SetLastError(WSAEFAULT); return SOCKET_ERROR; } /* Set the open type */ Thread->OpenType = *optval; return ERROR_SUCCESS; } /* 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 */ INT WSAAPI WSAStringToAddressW(IN LPWSTR AddressString, IN INT AddressFamily, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, OUT LPSOCKADDR lpAddress, IN OUT LPINT lpAddressLength) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode, Status; DWORD CatalogEntryId; PTCATALOG Catalog; PTCATALOG_ENTRY CatalogEntry; DPRINT("WSAStringToAddressW: %S\n", AddressString); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return SOCKET_ERROR; } /* Get the catalog */ Catalog = WsProcGetTCatalog(Process); /* Check if we got custom protocol info */ if (lpProtocolInfo) { /* Get the entry ID */ CatalogEntryId = lpProtocolInfo->dwCatalogEntryId; /* Get the entry associated with it */ ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog, CatalogEntryId, &CatalogEntry); } else { /* Get it from the address family */ ErrorCode = WsTcGetEntryFromAf(Catalog, AddressFamily, &CatalogEntry); } /* Check for success */ if (ErrorCode == ERROR_SUCCESS) { /* Call the provider */ Status = CatalogEntry->Provider->Service.lpWSPStringToAddress(AddressString, AddressFamily, &CatalogEntry-> ProtocolInfo, lpAddress, lpAddressLength, &ErrorCode); /* Dereference the entry */ WsTcEntryDereference(CatalogEntry); /* Check for success and return */ if (Status == ERROR_SUCCESS) return ERROR_SUCCESS; } /* Set the error and return */ SetLastError(ErrorCode); return SOCKET_ERROR; }
/* * @implemented */ PSERVENT WSAAPI getservbyname(IN const char FAR * name, IN const char FAR * proto) { PSERVENT Servent; LPBLOB Blob; CHAR ResultsBuffer[RNR_BUFFER_SIZE]; PCHAR Results = ResultsBuffer; PCHAR PortName; PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; DPRINT("getservbyname: %s\n", name); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return NULL; } /* No protocol specifed */ if(!proto) proto = ""; /* Allocate buffer for it */ PortName = HeapAlloc(WsSockHeap, 0, strlen(proto) + 1 + strlen(name) + 1); if (!PortName) { /* Fail */ SetLastError(WSA_NOT_ENOUGH_MEMORY); return NULL; } /* Put it into the right syntax */ sprintf(PortName, "%s/%s", name, proto); /* Get the Service in a Blob */ Blob = getxyDataEnt(&Results, RNR_BUFFER_SIZE, PortName, &IANAGuid, 0); /* Free the string we sent */ HeapFree(WsSockHeap, 0, PortName); /* Check if we got a blob */ if(Blob) { /* Copy the blob to our buffer and convert it */ Servent = WsThreadBlobToServent(Thread, Blob); /* Unpack the hostent */ if(Servent) UnpackServEnt(Servent); } else { /* We failed, so zero it out */ Servent = 0; /* Normalize the error message */ if(GetLastError() == WSATYPE_NOT_FOUND) SetLastError(WSANO_DATA); } /* Check if we received a newly allocated buffer; free it. */ if (Results != ResultsBuffer) HeapFree(WsSockHeap, 0, Results); /* Return the hostent */ return Servent; }