⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ns.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * COPYRIGHT:   See COPYING in the top level directory
 * PROJECT:     ReactOS WinSock 2 DLL
 * FILE:        misc/ns.c
 * PURPOSE:     Namespace APIs
 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
 * REVISIONS:
 *   CSH 01/09-2000 Created
 */
#define __NO_CTYPE_INLINES
#include <ctype.h>
#include <ws2_32.h>
#include <winbase.h>

#ifndef BUFSIZ
#define BUFSIZ 1024
#endif/*BUFSIZ*/

#ifndef MAX_HOSTNAME_LEN
#define MAX_HOSTNAME_LEN 256
#endif

/* Name resolution APIs */

/*
 * @unimplemented
 */
INT
EXPORT
WSAAddressToStringA(
    IN      LPSOCKADDR lpsaAddress,
    IN      DWORD dwAddressLength,
    IN      LPWSAPROTOCOL_INFOA lpProtocolInfo,
    OUT     LPSTR lpszAddressString,
    IN OUT  LPDWORD lpdwAddressStringLength)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAAddressToStringW(
    IN      LPSOCKADDR lpsaAddress,
    IN      DWORD dwAddressLength,
    IN      LPWSAPROTOCOL_INFOW lpProtocolInfo,
    OUT     LPWSTR lpszAddressString,
    IN OUT  LPDWORD lpdwAddressStringLength)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAEnumNameSpaceProvidersA(
    IN OUT  LPDWORD lpdwBufferLength,
    OUT     LPWSANAMESPACE_INFOA lpnspBuffer)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAEnumNameSpaceProvidersW(
    IN OUT  LPDWORD lpdwBufferLength,
    OUT     LPWSANAMESPACE_INFOW lpnspBuffer)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAGetServiceClassInfoA(
    IN      LPGUID lpProviderId,
    IN      LPGUID lpServiceClassId,
    IN OUT  LPDWORD lpdwBufferLength,
    OUT     LPWSASERVICECLASSINFOA lpServiceClassInfo)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAGetServiceClassInfoW(
    IN      LPGUID lpProviderId,
    IN      LPGUID lpServiceClassId,
    IN OUT  LPDWORD lpdwBufferLength,
    OUT     LPWSASERVICECLASSINFOW lpServiceClassInfo)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAGetServiceClassNameByClassIdA(
    IN      LPGUID lpServiceClassId,
    OUT     LPSTR lpszServiceClassName,
    IN OUT  LPDWORD lpdwBufferLength)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAGetServiceClassNameByClassIdW(
    IN      LPGUID lpServiceClassId,
    OUT     LPWSTR lpszServiceClassName,
    IN OUT  LPDWORD lpdwBufferLength)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAInstallServiceClassA(
    IN  LPWSASERVICECLASSINFOA lpServiceClassInfo)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAInstallServiceClassW(
    IN  LPWSASERVICECLASSINFOW lpServiceClassInfo)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSALookupServiceBeginA(
    IN  LPWSAQUERYSETA lpqsRestrictions,
    IN  DWORD dwControlFlags,
    OUT LPHANDLE lphLookup)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSALookupServiceBeginW(
    IN  LPWSAQUERYSETW lpqsRestrictions,
    IN  DWORD dwControlFlags,
    OUT LPHANDLE lphLookup)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSALookupServiceEnd(
    IN  HANDLE hLookup)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSALookupServiceNextA(
    IN      HANDLE hLookup,
    IN      DWORD dwControlFlags,
    IN OUT  LPDWORD lpdwBufferLength,
    OUT     LPWSAQUERYSETA lpqsResults)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSALookupServiceNextW(
    IN      HANDLE hLookup,
    IN      DWORD dwControlFlags,
    IN OUT  LPDWORD lpdwBufferLength,
    OUT     LPWSAQUERYSETW lpqsResults)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSARemoveServiceClass(
    IN  LPGUID lpServiceClassId)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSASetServiceA(
    IN  LPWSAQUERYSETA lpqsRegInfo,
    IN  WSAESETSERVICEOP essOperation,
    IN  DWORD dwControlFlags)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSASetServiceW(
    IN  LPWSAQUERYSETW lpqsRegInfo,
    IN  WSAESETSERVICEOP essOperation,
    IN  DWORD dwControlFlags)
{
    UNIMPLEMENTED

    return 0;
}


/*
 * @unimplemented
 */
INT
EXPORT
WSAStringToAddressA(
    IN      LPSTR AddressString,
    IN      INT AddressFamily,
    IN      LPWSAPROTOCOL_INFOA lpProtocolInfo,
    OUT     LPSOCKADDR lpAddress,
    IN OUT  LPINT lpAddressLength)
{
    INT ret, len;
	LPWSTR szTemp;
	LPWSAPROTOCOL_INFOW lpProtoInfoW = NULL;

	len = MultiByteToWideChar( CP_ACP, 0, AddressString, -1, NULL, 0 );
	szTemp = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );	
	MultiByteToWideChar( CP_ACP, 0, AddressString, -1, szTemp, len );
	
    if (lpProtocolInfo)
	{
	 len =   WSAPROTOCOL_LEN+1;
	 lpProtoInfoW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );	
   
	 memcpy( lpProtoInfoW, lpProtocolInfo, sizeof(LPWSAPROTOCOL_INFOA));

	 MultiByteToWideChar( CP_ACP, 0, lpProtocolInfo->szProtocol, -1, lpProtoInfoW->szProtocol, len );
	}
         
	ret = WSAStringToAddressW(szTemp, AddressFamily, lpProtoInfoW, lpAddress, lpAddressLength);

	HeapFree( GetProcessHeap(), 0, szTemp );

	if (lpProtocolInfo)
	   HeapFree( GetProcessHeap(), 0, lpProtoInfoW );
	
	WSASetLastError(ret);
    return ret;
}



/*
 * @implement 
 */
INT
EXPORT
WSAStringToAddressW(
    IN      LPWSTR AddressString,
    IN      INT AddressFamily,
    IN      LPWSAPROTOCOL_INFOW lpProtocolInfo,
    OUT     LPSOCKADDR lpAddress,
    IN OUT  LPINT lpAddressLength)
{
    int pos=0;		
	int res=0;
	LONG inetaddr = 0;	
    LPWSTR *bp=NULL;

	SOCKADDR_IN *sockaddr = (SOCKADDR_IN *) lpAddress;

	if (!lpAddressLength || !lpAddress) 
		return SOCKET_ERROR;
	
	if (AddressString==NULL) 
		return WSAEINVAL;
    		
    /* Set right adress family */
    if (lpProtocolInfo!=NULL) 
	   sockaddr->sin_family = lpProtocolInfo->iAddressFamily;

	else sockaddr->sin_family = AddressFamily; 	
   
	/* Report size */
	if (AddressFamily == AF_INET)
	{
		if (*lpAddressLength < (INT)sizeof(SOCKADDR_IN))
		{
			*lpAddressLength = sizeof(SOCKADDR_IN);
		    res = WSAEFAULT;
		}
		else
		{
         if (!lpAddress) 
			res = WSAEINVAL;
		 else 
		 {
		  // translate now ip string to ip

		  /* rest sockaddr.sin_addr.s_addr  
		     for we need to be sure it is zero when we come to while */
		  memset(lpAddress,0,sizeof(SOCKADDR_IN));

		  /* Set right adress family */
          sockaddr->sin_family = AF_INET;

		  /* Get port number */
		  pos = wcscspn(AddressString,L":") + 1;
		  if (pos < (int)wcslen(AddressString))
	          sockaddr->sin_port = wcstol(&AddressString[pos],bp,10); 		   		   

		   else
			   sockaddr->sin_port = 0;
          		  
		  /* Get ip number */		  
		  pos=0;
		  inetaddr=0;

          while (pos < (int)wcslen(AddressString))
          {	      
	       inetaddr = (inetaddr<<8) + ((UCHAR)wcstol(&AddressString[pos],bp,10));	 	           
	       pos += wcscspn( &AddressString[pos],L".") +1 ;	 	       		   
	       }

          res = 0;
		  sockaddr->sin_addr.s_addr = inetaddr;				  
		  }

		}
	}

    WSASetLastError(res);
	if (!res) return 0;			
    return SOCKET_ERROR;	    
}

void check_hostent(struct hostent **he) {
  struct hostent *new_he;
  WS_DbgPrint(MID_TRACE,("*he: %x\n",*he));
  if(!*he) {
    new_he = HeapAlloc(GlobalHeap, 0, sizeof(struct hostent) + MAX_HOSTNAME_LEN + 1);
    new_he->h_name = (PCHAR)(new_he + 1);
    new_he->h_aliases = 0;
    new_he->h_addrtype = 0; // AF_INET
    new_he->h_length = 0;   // sizeof(in_addr)
    new_he->h_addr_list = HeapAlloc(GlobalHeap, 0, sizeof(char *) * 2);
    RtlZeroMemory(new_he->h_addr_list, sizeof(char *) * 2);
    *he = new_he;
  }
}

void populate_hostent(struct hostent *he, char* name, DNS_A_DATA addr) {
  ASSERT(he);
  //he = HeapAlloc(GlobalHeap, 0, sizeof(struct hostent));
  //he->h_name = HeapAlloc(GlobalHeap, 0, MAX_HOSTNAME_LEN+1);
  strncpy(he->h_name, name, MAX_HOSTNAME_LEN);
  he->h_aliases = 0;
  he->h_addrtype = AF_INET;
  he->h_length = sizeof(IN_ADDR); //sizeof(struct in_addr);
  if( he->h_addr_list[0] ) HeapFree( GlobalHeap, 0, he->h_addr_list[0] );
  he->h_addr_list[0] = HeapAlloc(GlobalHeap, 0, MAX_HOSTNAME_LEN+1);
  WS_DbgPrint(MID_TRACE,("he->h_addr_list[0] %x\n", he->h_addr_list[0]));
  RtlCopyMemory(he->h_addr_list[0], (char*)&addr.IpAddress, 
		sizeof(addr.IpAddress));
  he->h_addr_list[1] = 0;
}


#define HFREE(x) if(x) { HeapFree(GlobalHeap, 0, (x)); x=0; }
void free_hostent(struct hostent *he) {
  if(he) {
    HFREE(he->h_name);
    char *next = he->h_aliases[0];
    while(next) { HFREE(next); next++; }
    next = he->h_addr_list[0];
    while(next) { HFREE(next); next++; }
    HFREE(he->h_addr_list);
    HFREE(he);
  }
}

/* WinSock 1.1 compatible name resolution APIs */

/*
 * @unimplemented
 */
LPHOSTENT
EXPORT
gethostbyaddr(
    IN  CONST CHAR FAR* addr,
    IN  INT len,
    IN  INT type)
{
    UNIMPLEMENTED

    return (LPHOSTENT)NULL;
}

/*
  Assumes rfc 1123 - adam * 
   addr[1] = 0;
    addr[0] = inet_addr(name);
    strcpy( hostname, name );
    if(addr[0] == 0xffffffff) return NULL;
    he.h_addr_list = (void *)addr;
    he.h_name = hostname;
    he.h_aliases = NULL;
    he.h_addrtype = AF_INET;
    he.h_length = sizeof(addr);
    return &he;

<RANT>
From the MSDN Platform SDK: Windows Sockets 2
"The gethostbyname function cannot resolve IP address strings passed to it.
Such a request is treated exactly as if an unknown host name were passed."
</RANT>

Defferring to the the documented behaviour, rather than the unix behaviour
What if the hostname is in the HOSTS file? see getservbyname

 * @implemented
 */

/* DnsQuery -- lib/dnsapi/dnsapi/query.c */
   /* see ws2_32.h, winsock2.h*/
    /*getnetworkparameters - iphlp api */
/*
REFERENCES

servent -- w32api/include/winsock2.h
PWINSOCK_THREAD_BLOCK -- ws2_32.h
dllmain.c -- threadlocal memory allocation / deallocation
lib/dnsapi
      

*/
      /* lib/adns/src/adns.h XXX */


/*
struct  hostent {
        char    *h_name;
        char    **h_aliases;
        short   h_addrtype;
        short   h_length;
        char    **h_addr_list;
#define h_addr h_addr_list[0]
};
struct  servent {
        char    *s_name;
        char    **s_aliases;
        short   s_port;
        char    *s_proto;
};


struct hostent defined in w32api/include/winsock2.h
*/

void free_servent(struct servent* s) {
  HFREE(s->s_name);
  char* next = s->s_aliases[0];
  while(next) { HFREE(next); next++; }
  s->s_port = 0;
  HFREE(s->s_proto);
  HFREE(s);
}


 
LPHOSTENT
EXPORT
gethostbyname(
    IN  CONST CHAR FAR* name)
{
  enum addr_type{ GH_INVALID, GH_IPV6, GH_IPV4, GH_RFC1123_DNS };
  typedef enum addr_type addr_type;
  addr_type addr;
  int ret = 0;
  char* found = 0;
  DNS_STATUS dns_status = {0};
  /* include/WinDNS.h -- look up DNS_RECORD on MSDN */
  PDNS_RECORD dp = 0;

  addr = GH_INVALID;

  PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;

  if( !p ) {
    WSASetLastError( WSANOTINITIALISED );
    return NULL;
  }

  check_hostent(&p->Hostent);   /*XXX alloc_hostent*/

  /* Hostname NULL - behave like gethostname */
  if(name == NULL) {
    ret = gethostname(p->Hostent->h_name, MAX_HOSTNAME_LEN);
    return p->Hostent;
  }

  if(ret) {
    WSASetLastError( WSAHOST_NOT_FOUND ); //WSANO_DATA  ??
    return NULL;
  }

  /* Is it an IPv6 address? */
  found = strstr(name, ":");
  if( found != NULL ) {
    addr = GH_IPV6;
    goto act;
  }

  /* Is it an IPv4 address? */
  if (!isalpha(name[0])) {
    addr = GH_IPV4;
    goto act;
  }

 addr = GH_RFC1123_DNS;

 /* Broken out in case we want to get fancy later */
 act:
    switch(addr){
      case GH_IPV6:
	WSASetLastError(STATUS_NOT_IMPLEMENTED);
	return NULL;
	break;

    case GH_INVALID:
      WSASetLastError(WSAEFAULT);
      return NULL;
      break;

    /* Note: If passed an IP address, MSDN says that gethostbyname()
             treats it as an unknown host.
       This is different from the unix implementation. Use inet_addr()
    */
    case GH_IPV4:
    case GH_RFC1123_DNS:
      /* DNS_TYPE_A: include/WinDNS.h */
      /* DnsQuery -- lib/dnsapi/dnsapi/query.c */
      dns_status = DnsQuery_A ( name, DNS_TYPE_A, DNS_QUERY_STANDARD,
				0, /* extra dns servers */ &dp, 0 );

      if(dns_status == 0) {
	//ASSERT(dp->wType == DNS_TYPE_A);
	//ASSERT(dp->wDataLength == sizeof(DNS_A_DATA));
	PDNS_RECORD curr;
	for(curr=dp;
	    curr != NULL && curr->wType != DNS_TYPE_A;
	    curr = curr->pNext ) { 
	  WS_DbgPrint(MID_TRACE,("wType: %i\n", curr->wType));
	  /*empty */ 
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -