#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef  __CRT__NO_INLINE
#define __CRT__NO_INLINE
#include <wspiapi.h>

char *WINAPI WspiapiStrdup (const char *pszString)
{
  char *pszMemory;
  size_t cchMemory;
  if(!pszString) return(NULL);
  cchMemory = strlen(pszString) + 1;
  pszMemory = (char *) WspiapiMalloc(cchMemory);
  if(!pszMemory) return(NULL);
  _WSPIAPI_STRCPY_S(pszMemory,cchMemory,pszString);
  return pszMemory;
}

WINBOOL WINAPI
WspiapiParseV4Address (const char *pszAddress,PDWORD pdwAddress)
{
  DWORD dwAddress = 0;
  const char *pcNext = NULL;
  int iCount = 0;
  for(pcNext = pszAddress;*pcNext!='\0';pcNext++)
    if(*pcNext=='.') iCount++;
  if(iCount!=3) return FALSE;
  dwAddress = inet_addr(pszAddress);
  if(dwAddress==INADDR_NONE) return FALSE;
  *pdwAddress = dwAddress;
  return TRUE;
}

struct addrinfo * WINAPI
WspiapiNewAddrInfo (int iSocketType,int iProtocol,WORD wPort,DWORD dwAddress)
{
  struct addrinfo *ptNew;
  struct sockaddr_in *ptAddress;
  ptNew = (struct addrinfo *) WspiapiMalloc(sizeof(struct addrinfo));
  if(!ptNew) return NULL;
  ptAddress = (struct sockaddr_in *) WspiapiMalloc(sizeof(struct sockaddr_in));
  if(!ptAddress) {
    WspiapiFree(ptNew);
    return NULL;
  }
  ptAddress->sin_family = AF_INET;
  ptAddress->sin_port = wPort;
  ptAddress->sin_addr.s_addr = dwAddress;
  ptNew->ai_family = PF_INET;
  ptNew->ai_socktype = iSocketType;
  ptNew->ai_protocol = iProtocol;
  ptNew->ai_addrlen = sizeof(struct sockaddr_in);
  ptNew->ai_addr = (struct sockaddr *) ptAddress;
  return ptNew;
}

int WINAPI
WspiapiQueryDNS(const char *pszNodeName,int iSocketType,int iProtocol,WORD wPort,char pszAlias[NI_MAXHOST],struct addrinfo **pptResult)
{
  struct addrinfo **pptNext = pptResult;
  struct hostent *ptHost = NULL;
  char **ppAddresses;
  *pptNext = NULL;
  pszAlias[0] = '\0';
  ptHost = gethostbyname(pszNodeName);
  if(ptHost) {
    if((ptHost->h_addrtype==AF_INET) && (ptHost->h_length==sizeof(struct in_addr))) {
      for(ppAddresses = ptHost->h_addr_list;*ppAddresses!=NULL;ppAddresses++) {
	*pptNext = WspiapiNewAddrInfo(iSocketType,iProtocol,wPort,((struct in_addr *) *ppAddresses)->s_addr);
	if(!*pptNext) return EAI_MEMORY;
	pptNext = &((*pptNext)->ai_next);
      }
    }
    _WSPIAPI_STRNCPY_S(pszAlias,NI_MAXHOST,ptHost->h_name,NI_MAXHOST - 1);
    return 0;
  }
  switch(WSAGetLastError()) {
		case WSAHOST_NOT_FOUND: return EAI_NONAME;
		case WSATRY_AGAIN: return EAI_AGAIN;
		case WSANO_RECOVERY: return EAI_FAIL;
		case WSANO_DATA: return EAI_NODATA;
		default: return EAI_NONAME;
  }
}

int WINAPI
WspiapiLookupNode(const char *pszNodeName,int iSocketType,int iProtocol,WORD wPort,WINBOOL bAI_CANONNAME,struct addrinfo **pptResult)
{
  int iError = 0;
  int iAliasCount = 0;
  char szFQDN1[NI_MAXHOST] = "";
  char szFQDN2[NI_MAXHOST] = "";
  char *pszName = szFQDN1;
  char *pszAlias = szFQDN2;
  char *pszScratch = NULL;
  _WSPIAPI_STRNCPY_S(pszName,NI_MAXHOST,pszNodeName,NI_MAXHOST - 1);
  for(;;) {
    iError = WspiapiQueryDNS(pszNodeName,iSocketType,iProtocol,wPort,pszAlias,pptResult);
    if(iError) break;
    if(*pptResult) break;
    if((!strlen(pszAlias)) || (!strcmp(pszName,pszAlias)) || (++iAliasCount==16)) {
      iError = EAI_FAIL;
      break;
    }
    WspiapiSwap(pszName,pszAlias,pszScratch);
  }
  if(!iError && bAI_CANONNAME) {
    (*pptResult)->ai_canonname = WspiapiStrdup(pszAlias);
    if(!(*pptResult)->ai_canonname) iError = EAI_MEMORY;
  }
  return iError;
}

int WINAPI
WspiapiClone (WORD wPort,struct addrinfo *ptResult)
{
  struct addrinfo *ptNext = NULL;
  struct addrinfo *ptNew = NULL;
  for(ptNext = ptResult; ptNext!=NULL;) {
    ptNew = WspiapiNewAddrInfo(SOCK_DGRAM,ptNext->ai_protocol,wPort,((struct sockaddr_in *) ptNext->ai_addr)->sin_addr.s_addr);
    if(!ptNew) break;
    ptNew->ai_next = ptNext->ai_next;
    ptNext->ai_next = ptNew;
    ptNext = ptNew->ai_next;
  }
  if(ptNext!=NULL) return EAI_MEMORY;
  return 0;
}

void WINAPI WspiapiLegacyFreeAddrInfo (struct addrinfo *ptHead)
{
  struct addrinfo *ptNext;
  for(ptNext = ptHead;ptNext!=NULL;ptNext = ptHead) {
    if(ptNext->ai_canonname) WspiapiFree(ptNext->ai_canonname);
    if(ptNext->ai_addr) WspiapiFree(ptNext->ai_addr);
    ptHead = ptNext->ai_next;
    WspiapiFree(ptNext);
  }
}

int WINAPI
WspiapiLegacyGetAddrInfo(const char *pszNodeName,const char *pszServiceName,const struct addrinfo *ptHints,struct addrinfo **pptResult)
{
  int iError = 0;
  int iFlags = 0;
  int iFamily = PF_UNSPEC;
  int iSocketType = 0;
  int iProtocol = 0;
  WORD wPort = 0;
  DWORD dwAddress = 0;
  struct servent *ptService = NULL;
  char *pc = NULL;
  WINBOOL bClone = FALSE;
  WORD wTcpPort = 0;
  WORD wUdpPort = 0;
  *pptResult = NULL;
  if((!pszNodeName) && (!pszServiceName)) return EAI_NONAME;
  if(ptHints) {
    if((ptHints->ai_addrlen!=0) || (ptHints->ai_canonname!=NULL) || (ptHints->ai_addr!=NULL) || (ptHints->ai_next!=NULL)) return EAI_FAIL;
    iFlags = ptHints->ai_flags;
    if((iFlags & AI_CANONNAME) && !pszNodeName) return EAI_BADFLAGS;
    iFamily = ptHints->ai_family;
    if((iFamily!=PF_UNSPEC) && (iFamily!=PF_INET)) return EAI_FAMILY;
    iSocketType = ptHints->ai_socktype;
    if((iSocketType!=0) && (iSocketType!=SOCK_STREAM) && (iSocketType!=SOCK_DGRAM) && (iSocketType!=SOCK_RAW)) return EAI_SOCKTYPE;
    iProtocol = ptHints->ai_protocol;
  }
  if(pszServiceName) {
    wPort = (WORD) strtoul(pszServiceName,&pc,10);
    if(*pc=='\0') {
      wPort = wTcpPort = wUdpPort = htons(wPort);
      if(iSocketType==0) {
	bClone = TRUE;
	iSocketType = SOCK_STREAM;
      }
    } else {
      if((iSocketType==0) || (iSocketType==SOCK_DGRAM)) {
	ptService = getservbyname(pszServiceName,"udp");
	if(ptService) wPort = wUdpPort = ptService->s_port;
      }
      if((iSocketType==0) || (iSocketType==SOCK_STREAM)) {
	ptService = getservbyname(pszServiceName,"tcp");
	if(ptService) wPort = wTcpPort = ptService->s_port;
      }
      if(wPort==0) return (iSocketType ? EAI_SERVICE : EAI_NONAME);
      if(iSocketType==0) {
	iSocketType = (wTcpPort) ? SOCK_STREAM : SOCK_DGRAM;
	bClone = (wTcpPort && wUdpPort);
      }
    }
  }
  if((!pszNodeName) || (WspiapiParseV4Address(pszNodeName,&dwAddress))) {
    if(!pszNodeName) {
      dwAddress = htonl((iFlags & AI_PASSIVE) ? INADDR_ANY : INADDR_LOOPBACK);
    }
    *pptResult = WspiapiNewAddrInfo(iSocketType,iProtocol,wPort,dwAddress);
    if(!(*pptResult)) iError = EAI_MEMORY;
    if(!iError && pszNodeName) {
      (*pptResult)->ai_flags |= AI_NUMERICHOST;
      if(iFlags & AI_CANONNAME) {
	(*pptResult)->ai_canonname =
	  WspiapiStrdup(inet_ntoa(*((struct in_addr *) &dwAddress)));
	if(!(*pptResult)->ai_canonname) iError = EAI_MEMORY;
      }
    }
  } else if(iFlags & AI_NUMERICHOST) iError = EAI_NONAME;
  else iError = WspiapiLookupNode(pszNodeName,iSocketType,iProtocol,wPort,(iFlags & AI_CANONNAME),pptResult);
  if(!iError && bClone) iError = WspiapiClone(wUdpPort,*pptResult);
  if(iError) {
    WspiapiLegacyFreeAddrInfo(*pptResult);
    *pptResult = NULL;
  }
  return (iError);
}

int WINAPI
WspiapiLegacyGetNameInfo(const struct sockaddr *ptSocketAddress,socklen_t tSocketLength,char *pszNodeName,size_t tNodeLength,char *pszServiceName,size_t tServiceLength,int iFlags)
{
  struct servent *ptService;
  WORD wPort;
  char szBuffer[] = "65535";
  char *pszService = szBuffer;
  struct hostent *ptHost;
  struct in_addr tAddress;
  char *pszNode = NULL;
  char *pc = NULL;

  if((!ptSocketAddress) || (tSocketLength < sizeof(struct sockaddr))) return EAI_FAIL;
  if(ptSocketAddress->sa_family!=AF_INET) return EAI_FAMILY;
  if(tSocketLength < sizeof(struct sockaddr_in)) return EAI_FAIL;
  if(!(pszNodeName && tNodeLength) && !(pszServiceName && tServiceLength)) return EAI_NONAME;
  if((iFlags & NI_NUMERICHOST) && (iFlags & NI_NAMEREQD)) return EAI_BADFLAGS;
  if(pszServiceName && tServiceLength) {
    wPort = ((struct sockaddr_in *) ptSocketAddress)->sin_port;
    if(iFlags & NI_NUMERICSERV) {
      _WSPIAPI_SPRINTF_S_1(szBuffer,_WSPIAPI_COUNTOF(szBuffer),"%u",ntohs(wPort));
    } else {
      ptService = getservbyport(wPort,(iFlags & NI_DGRAM) ? "udp" : NULL);
      if(ptService && ptService->s_name) {
	pszService = ptService->s_name;
      } else {
	_WSPIAPI_SPRINTF_S_1(szBuffer,_WSPIAPI_COUNTOF(szBuffer),"%u",ntohs(wPort));
      }
    }
    if(tServiceLength > strlen(pszService))
      _WSPIAPI_STRCPY_S(pszServiceName,tServiceLength,pszService);
    else return EAI_FAIL;
  }
  if(pszNodeName && tNodeLength) {
    tAddress = ((struct sockaddr_in *) ptSocketAddress)->sin_addr;
    if(iFlags & NI_NUMERICHOST) {
      pszNode = inet_ntoa(tAddress);
    } else {
      ptHost = gethostbyaddr((char *) &tAddress,sizeof(struct in_addr),AF_INET);
      if(ptHost && ptHost->h_name) {
	pszNode = ptHost->h_name;
	if((iFlags & NI_NOFQDN) && ((pc = strchr(pszNode,'.'))!=NULL)) *pc = '\0';
      } else {
	if(iFlags & NI_NAMEREQD) {
	  switch(WSAGetLastError()) {
						case WSAHOST_NOT_FOUND: return EAI_NONAME;
						case WSATRY_AGAIN: return EAI_AGAIN;
						case WSANO_RECOVERY: return EAI_FAIL;
						default: return EAI_NONAME;
	  }
	} else pszNode = inet_ntoa(tAddress);
      }
    }
    if(tNodeLength > strlen(pszNode)) _WSPIAPI_STRCPY_S(pszNodeName,tNodeLength,pszNode);
    else return EAI_FAIL;
  }
  return 0;
}

FARPROC WINAPI
WspiapiLoad (WORD wFunction)
{
  HMODULE hLibrary = NULL;
  static WINBOOL bInitialized = FALSE;
  static WSPIAPI_FUNCTION rgtGlobal[] = WSPIAPI_FUNCTION_ARRAY;
  static const int iNumGlobal = (sizeof(rgtGlobal) / sizeof(WSPIAPI_FUNCTION));
  WSPIAPI_FUNCTION rgtLocal[] = WSPIAPI_FUNCTION_ARRAY;
  FARPROC fScratch = NULL;
  int i = 0;
  if(bInitialized) return (rgtGlobal[wFunction].pfAddress);
  for(;;) {
    CHAR SystemDir[MAX_PATH + 1];
    CHAR Path[MAX_PATH + 8];
    if(GetSystemDirectoryA(SystemDir,MAX_PATH)==0) break;
    _WSPIAPI_STRCPY_S(Path,_WSPIAPI_COUNTOF(Path),SystemDir);
    _WSPIAPI_STRCAT_S(Path,_WSPIAPI_COUNTOF(Path),"\\ws2_32");
    hLibrary = LoadLibraryA(Path);
    if(hLibrary!=NULL) {
      fScratch = GetProcAddress(hLibrary,"getaddrinfo");
      if(!fScratch) {
	FreeLibrary(hLibrary);
	hLibrary = NULL;
      }
    }
    if(hLibrary!=NULL) break;
    _WSPIAPI_STRCPY_S(Path,_WSPIAPI_COUNTOF(Path),SystemDir);
    _WSPIAPI_STRCAT_S(Path,_WSPIAPI_COUNTOF(Path),"\\wship6");
    hLibrary = LoadLibraryA(Path);
    if(hLibrary!=NULL) {
      fScratch = GetProcAddress(hLibrary,"getaddrinfo");
      if(!fScratch) {
	FreeLibrary(hLibrary);
	hLibrary = NULL;
      }
    }
    break;
  }
  if(hLibrary!=NULL) {
    for(i = 0;i < iNumGlobal;i++) {
      rgtLocal[i].pfAddress = GetProcAddress(hLibrary,rgtLocal[i].pszName);
      if(!(rgtLocal[i].pfAddress)) {
	FreeLibrary(hLibrary);
	hLibrary = NULL;
	break;
      }
    }
    if(hLibrary!=NULL) {
      for(i = 0;i < iNumGlobal;i++)
	rgtGlobal[i].pfAddress = rgtLocal[i].pfAddress;
    }
  }
  bInitialized = TRUE;
  return (rgtGlobal[wFunction].pfAddress);
}

int WINAPI WspiapiGetAddrInfo(const char *nodename,const char *servname,const struct addrinfo *hints,struct addrinfo **res)
{
  int iError;
  static WSPIAPI_PGETADDRINFO pfGetAddrInfo = NULL;
  if(!pfGetAddrInfo) pfGetAddrInfo = (WSPIAPI_PGETADDRINFO) WspiapiLoad(0);
  iError = (*pfGetAddrInfo)(nodename,servname,hints,res);
  WSASetLastError(iError);
  return iError;
}

int WINAPI
WspiapiGetNameInfo (const struct sockaddr *sa,socklen_t salen,char *host,size_t hostlen,char *serv,size_t servlen,int flags)
{
  int iError;
  static WSPIAPI_PGETNAMEINFO pfGetNameInfo = NULL;
  if(!pfGetNameInfo) pfGetNameInfo = (WSPIAPI_PGETNAMEINFO) WspiapiLoad(1);
  iError = (*pfGetNameInfo)(sa,salen,host,hostlen,serv,servlen,flags);
  WSASetLastError(iError);
  return iError;
}

void WINAPI
WspiapiFreeAddrInfo (struct addrinfo *ai)
{
  static WSPIAPI_PFREEADDRINFO pfFreeAddrInfo = NULL;
  if(!pfFreeAddrInfo) pfFreeAddrInfo = (WSPIAPI_PFREEADDRINFO) WspiapiLoad(2);
  (*pfFreeAddrInfo)(ai);
}
