Beispiel #1
0
int
main (int argc, char **argv)
{
    int ret;
    int r = 1;
    WSADATA wsd;
    GUID prov;
    GUID sc;
    wchar_t *cmdl;
    int wargc;
    wchar_t **wargv;

    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());
        return 5;
    }

    cmdl = GetCommandLineW ();
    if (cmdl == NULL)
    {
        WSACleanup();
        return 2;
    }
    wargv = CommandLineToArgvW (cmdl, &wargc);
    if (wargv == NULL)
    {
        WSACleanup();
        return 3;
    }
    r = 4;

    if (wargc == 5)
    {
        if (wcscmp (wargv[1], L"A") == 0)
            sc = SVCID_DNS_TYPE_A;
        else if (wcscmp (wargv[1], L"AAAA") == 0)
            sc = SVCID_DNS_TYPE_AAAA;
        else if (wcscmp (wargv[1], L"name") == 0)
            sc = SVCID_HOSTNAME;
        else if (wcscmp (wargv[1], L"addr") == 0)
            sc = SVCID_INET_HOSTADDRBYNAME;
        else
            wargc -= 1;
        if (wcscmp (wargv[4], L"mswdns") == 0)
            prov = W32_DNS;
        else if (wcscmp (wargv[4], L"gnunetdns") == 0)
            prov = GNUNET_NAMESPACE_PROVIDER_DNS;
        else
            wargc -= 1;
    }
    else if (wargc == 3)
    {
    }
    else
    {
        fprintf (stderr, "Usage: %S <record type> <service name> <NSP library path> <NSP id>\n"
                 "record type      - one of the following: A | AAAA | name | addr\n"
                 "service name     - a string to resolve; \" \" (a space) means 'blank'\n"
                 "NSP library path - path to libw32nsp\n"
                 "NSP id           - one of the following: mswdns | gnunetdns\n",
                 wargv[0]);
    }

    if (wargc == 5)
    {
        HMODULE nsp;

        nsp = LoadLibraryW (wargv[3]);
        if (nsp == NULL)
        {
            fprintf (stderr, "Failed to load library `%S'\n", wargv[3]);
        }
        else
        {
            LPNSPSTARTUP startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup");
            if (startup == NULL)
                startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup@8");
            if (startup != NULL)
            {
                NSP_ROUTINE api;
                api.cbSize = sizeof (api);
                ret = startup (&prov, &api);
                if (NO_ERROR != ret)
                    fprintf (stderr, "startup failed: %lu\n", GetLastError ());
                else
                {
                    HANDLE lookup;
                    WSAQUERYSETW search;
                    char buf[4096];
                    WSAQUERYSETW *result = (WSAQUERYSETW *) buf;
                    DWORD resultsize;
                    DWORD err;
                    memset (&search, 0, sizeof (search));
                    search.dwSize = sizeof (search);
                    search.lpszServiceInstanceName = (wcscmp (wargv[2], L" ") == 0) ? NULL : wargv[2];
                    search.lpServiceClassId = &sc;
                    search.lpNSProviderId = &prov;
                    search.dwNameSpace = NS_ALL;
                    ret = api.NSPLookupServiceBegin (&prov, &search, NULL, LUP_RETURN_ALL, &lookup);
                    if (ret != NO_ERROR)
                    {
                        fprintf (stderr, "lookup start failed\n");
                    }
                    else
                    {
                        resultsize = 4096;
                        ret = api.NSPLookupServiceNext (lookup, LUP_RETURN_ALL, &resultsize, result);
                        err = GetLastError ();
                        if (ret != NO_ERROR)
                        {
                            fprintf (stderr, "lookup next failed: %lu\n", err);
                        }
                        else
                        {
                            int i;
                            printf ("Got result:\n");
                            printf ("  lpszServiceInstanceName: %S\n", result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL");
                            if (result->lpServiceClassId)
                                printf ("  lpServiceClassId:        { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n",
                                        result->lpServiceClassId->Data1, result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, result->lpServiceClassId->Data4[0],
                                        result->lpServiceClassId->Data4[1], result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], result->lpServiceClassId->Data4[4],
                                        result->lpServiceClassId->Data4[5], result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]);
                            else
                                printf ("  lpServiceClassId:        NULL\n");
                            if (result->lpVersion)
                                printf ("  lpVersion:               0x%08lX, %d\n", result->lpVersion->dwVersion, result->lpVersion->ecHow);
                            else
                                printf ("  lpVersion:               NULL\n");
                            printf ("  lpszComment:             %S\n", result->lpszComment ? result->lpszComment : L"NULL");
                            printf ("  dwNameSpace:             %lu\n", result->dwNameSpace);
                            if (result->lpNSProviderId)
                                printf ("  lpNSProviderId:          { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n",
                                        result->lpNSProviderId->Data1, result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, result->lpNSProviderId->Data4[0],
                                        result->lpNSProviderId->Data4[1], result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], result->lpNSProviderId->Data4[4],
                                        result->lpNSProviderId->Data4[5], result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]);
                            else
                                printf ("  lpNSProviderId:          NULL\n");
                            printf ("  lpszContext:             %S\n", result->lpszContext ? result->lpszContext : L"NULL");
                            printf ("  dwNumberOfProtocols:     %lu\n", result->dwNumberOfProtocols);
                            printf ("  lpszQueryString:         %S\n", result->lpszQueryString ? result->lpszQueryString : L"NULL");
                            printf ("  dwNumberOfCsAddrs:       %lu\n", result->dwNumberOfCsAddrs);
                            for (i = 0; i < result->dwNumberOfCsAddrs; i++)
                            {
                                switch (result->lpcsaBuffer[i].iSocketType)
                                {
                                case SOCK_STREAM:
                                    printf ("    %d: iSocketType = SOCK_STREAM\n", i);
                                    break;
                                case SOCK_DGRAM:
                                    printf ("    %d: iSocketType = SOCK_DGRAM\n", i);
                                    break;
                                default:
                                    printf ("    %d: iSocketType = %d\n", i, result->lpcsaBuffer[i].iSocketType);
                                }
                                switch (result->lpcsaBuffer[i].iProtocol)
                                {
                                case IPPROTO_TCP:
                                    printf ("    %d: iProtocol   = IPPROTO_TCP\n", i);
                                    break;
                                case IPPROTO_UDP:
                                    printf ("    %d: iProtocol   = IPPROTO_UDP\n", i);
                                    break;
                                default:
                                    printf ("    %d: iProtocol   = %d\n", i, result->lpcsaBuffer[i].iProtocol);
                                }
                                switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family)
                                {
                                case AF_INET:
                                    printf ("    %d: loc family  = AF_INET\n", i);
                                    break;
                                case AF_INET6:
                                    printf ("    %d: loc family  = AF_INET6\n", i);
                                    break;
                                default:
                                    printf ("    %d: loc family  = %hu\n", i, result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family);
                                }
                                switch (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family)
                                {
                                case AF_INET:
                                    printf ("    %d: rem family  = AF_INET\n", i);
                                    break;
                                case AF_INET6:
                                    printf ("    %d: rem family  = AF_INET6\n", i);
                                    break;
                                default:
                                    printf ("    %d: rem family = %hu\n", i, result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family);
                                }
                                char buf[1024];
                                DWORD buflen = 1024;
                                if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].LocalAddr.lpSockaddr, result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen))
                                    printf("\tLocal Address #%d: %s\n", i, buf);
                                else
                                    printf("\tLocal Address #%d: Can't convert: %lu\n", i, GetLastError ());
                                buflen = 1024;
                                if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen))
                                    printf("\tRemote Address #%d: %s\n", i, buf);
                                else
                                    printf("\tRemote Address #%d: Can't convert: %lu\n", i, GetLastError ());
                            }
                            printf ("  dwOutputFlags:           0x%08lX\n", result->dwOutputFlags);
                            printf ("  lpBlob:                  0x%p\n", result->lpBlob);
                            if (result->lpBlob)
                            {
                                struct hostent *he = malloc (result->lpBlob->cbSize);
                                if (he != NULL)
                                {
                                    GNUNET_memcpy (he, result->lpBlob->pBlobData, result->lpBlob->cbSize);
                                    UnpackHostEnt (he);
                                    print_hostent (he);
                                    free (he);
                                }
                            }
                        }
                        ret = api.NSPLookupServiceEnd (lookup);
                        if (ret != NO_ERROR)
                            printf ("NSPLookupServiceEnd() failed: %lu\n", GetLastError ());
                    }
                    api.NSPCleanup (&prov);
                }
            }
            FreeLibrary (nsp);
        }
    }
    else if (wargc == 3)
    {
        int s;
        ADDRINFOW hints;
        ADDRINFOW *result;
        ADDRINFOW *pos;

        memset (&hints, 0, sizeof (struct addrinfo));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;

        if (0 != (s = GetAddrInfoW (wargv[2], NULL, &hints, &result)))
        {
            fprintf (stderr, "Cound not resolve `%S' using GetAddrInfoW: %lu\n",
                     wargv[2], GetLastError ());
        }
        else
        {
            for (pos = result; pos != NULL; pos = pos->ai_next)
            {
                wchar_t tmpbuf[1024];
                DWORD buflen = 1024;
                if (0 == WSAAddressToStringW (pos->ai_addr, pos->ai_addrlen, NULL, tmpbuf, &buflen))
                    fprintf (stderr, "Result:\n"
                             "  flags: 0x%X\n"
                             "  family: 0x%X\n"
                             "  socktype: 0x%X\n"
                             "  protocol: 0x%X\n"
                             "  addrlen: %u\n"
                             "  addr: %S\n"
                             "  canonname: %S\n",
                             pos->ai_flags,
                             pos->ai_family,
                             pos->ai_socktype,
                             pos->ai_protocol,
                             pos->ai_addrlen,
                             tmpbuf,
                             pos->ai_canonname);
                else
                    fprintf (stderr, "Result:\n"
                             "  flags: 0x%X\n"
                             "  family: 0x%X\n"
                             "  socktype: 0x%X\n"
                             "  protocol: 0x%X\n"
                             "  addrlen: %u\n"
                             "  addr: %S\n"
                             "  canonname: %S\n",
                             pos->ai_flags,
                             pos->ai_family,
                             pos->ai_socktype,
                             pos->ai_protocol,
                             pos->ai_addrlen,
                             L"<can't stringify>",
                             pos->ai_canonname);
            }
            if (NULL != result)
                FreeAddrInfoW (result);
        }
    }
    WSACleanup();
    return r;
}
Beispiel #2
0
/*
 * @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;
}
Beispiel #3
0
//
// Function: main
//
// Description:
//    Initialize Winsock and set up the WSAQUERYSET structure
//    for querying DNS. We use the special GUID 
//    SVCID_INET_HOSTADDRBYNAME for name resolution and we
//    query on the UDP and TCP protocols. The information
//    is returned as a BLOB so we must specify the LUP_RETURN_BLOB
//    flag. Once the call to WSALookupServiceBegin/Next is 
//    successful then decode the BLOB data into a real HOSTENT
//    and print the results.
//
int main(int argc, char **argv)
{
    WSADATA        wsd;
    WSAQUERYSET   *qs=NULL;
    char           buff[RNR_BUFFER_SIZE];
    GUID           HostnameGuid = SVCID_INET_HOSTADDRBYNAME;
    HANDLE         hRnr;
    AFPROTOCOLS    afproto[2] = { {AF_INET, IPPROTO_UDP}, 
                                  {AF_INET, IPPROTO_TCP} };
    DWORD          dwLength=RNR_BUFFER_SIZE;
    int            ret, i;
    LPBLOB         pvRet=NULL;
    HOSTENT       *hp=NULL;
    SOCKADDR_IN    addr;

    // Check for proper usage
    //
    if (argc != 2)
    {
        printf("usage: %s hostname\n", argv[0]);
        return -1;
    }
    // Load Winsock
    //
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("WSAStartup() failed: %d\n", GetLastError());
        return -1;
    }
    // Initalize the WSAQUERYSET structure for the query
    //
    qs = (WSAQUERYSET *)buff;

    memset(qs, 0, sizeof(*qs));
    qs->dwSize = sizeof(WSAQUERYSET);
    qs->lpszServiceInstanceName = argv[1]; // name to resolve
    qs->lpServiceClassId = &HostnameGuid;
    qs->dwNameSpace = NS_ALL;              // or ND_DNS
    qs->dwNumberOfProtocols = 2;           // TCP and UDP
    qs->lpafpProtocols = afproto;
    
    ret = WSALookupServiceBegin(qs, LUP_RETURN_BLOB | LUP_RETURN_NAME,
                &hRnr);
    if (ret == NO_ERROR)
    {
        // We only have to call WSALookupServiceNext once because
        // the BLOB HOSTENT return will contain multiple addresses
        // if there are mutliple IP addresses associated with the
        // given name
        //
        ret = WSALookupServiceNext(hRnr, 0, &dwLength, qs);
        if (ret != NO_ERROR)
        {
            if (WSAGetLastError() == WSASERVICE_NOT_FOUND)
            {
                printf("No such name found!\n");
                WSALookupServiceEnd(hRnr);
                return 0;
            }
            printf("WSALookupServiceNext() failed: %d\n",
                WSAGetLastError());
        }
        WSALookupServiceEnd(hRnr);
    }
    // Make sure we got something returned
    //
    if (qs->lpBlob == NULL)
        return -1;
    //
    // Create our own buffer to hold the blob data
    //
    hp = (HOSTENT *)LocalAlloc(LPTR, qs->lpBlob->cbSize);
    if (!hp)
    {
        printf("LocalAlloc() failed: %d\n", GetLastError());
        return -1;
    }
    memcpy(hp, qs->lpBlob->pBlobData, qs->lpBlob->cbSize);
    //
    // Unpack the BLOB data so its meaningful
    //
    UnpackHostEnt(hp);
    //
    // Print out the addresses
    //
    for(i=0; hp->h_addr_list[i] ;i++)
    {
        memcpy(&addr.sin_addr, hp->h_addr_list[i], hp->h_length);
        printf("%s IP: %s\n", argv[1], inet_ntoa(addr.sin_addr));
    }
    for(i=0; hp->h_aliases[i] ;i++)
        printf("Alias: %s\n", hp->h_aliases[i]);

    // Cleanup
    //
    LocalFree(hp);

    WSACleanup();
    return 0;
}
Beispiel #4
0
/*
 * @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;
}
Beispiel #5
0
int
main (int argc, char **argv)
{
  int ret;
  int r = 1;
  WSADATA wsd;
  GUID *prov = NULL;
  GUID *sc = NULL;
  wchar_t *cmdl;
  int wargc;
  wchar_t **wargv;

  if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
  {
    fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError());
    return 5;
  }

  cmdl = GetCommandLineW ();
  if (cmdl == NULL)
  {
    WSACleanup();
    return 2;
  }
  wargv = CommandLineToArgvW (cmdl, &wargc);
  if (wargv == NULL)
  {
    WSACleanup();
    return 3;
  }
  r = 4;

  if (wargc == 5)
  {
    if (wcscmp (wargv[1], L"A") == 0)
      sc = &SVCID_DNS_TYPE_A;
    else if (wcscmp (wargv[1], L"AAAA") == 0)
      sc = &SVCID_DNS_TYPE_AAAA;
    else if (wcscmp (wargv[1], L"name") == 0)
      sc = &SVCID_HOSTNAME;
    else if (wcscmp (wargv[1], L"addr") == 0)
      sc = &SVCID_INET_HOSTADDRBYNAME;
    else
      wargc -= 1;
    if (wcscmp (wargv[4], L"mswdns") == 0)
      prov = &W32_DNS;
    else if (wcscmp (wargv[4], L"gnunetdns") == 0)
      prov = &GNUNET_NAMESPACE_PROVIDER_DNS;
    else
      wargc -= 1;
  }

  if (wargc == 5)
  {
    HMODULE nsp;
   
    nsp = LoadLibraryW (wargv[3]);
    if (nsp == NULL)
    {
      fprintf (stderr, "Failed to load library `%S'\n", wargv[3]);
    }
    else
    {
      LPNSPSTARTUP startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup");
      if (startup != NULL)
      {
        NSP_ROUTINE api;
        ret = startup (prov, &api);
        if (NO_ERROR != ret)
          fprintf (stderr, "startup failed\n");
        else
        {
          HANDLE lookup;
          WSAQUERYSETW search;
          char buf[4096];
          WSAQUERYSETW *result = (WSAQUERYSETW *) buf;
          DWORD resultsize;
          DWORD err;
          memset (&search, 0, sizeof (search));
          search.dwSize = sizeof (search);
          search.lpszServiceInstanceName = (wcscmp (wargv[2], L" ") == 0) ? NULL : wargv[2];
          search.lpServiceClassId = sc;
          search.lpNSProviderId = prov;
          search.dwNameSpace = NS_ALL;
          ret = api.NSPLookupServiceBegin (prov, &search, NULL, LUP_RETURN_ALL, &lookup);
          if (ret != NO_ERROR)
          {
            fprintf (stderr, "lookup start failed\n");
          }
          else
          {
            resultsize = 4096;
            ret = api.NSPLookupServiceNext (lookup, LUP_RETURN_ALL, &resultsize, result);
            err = GetLastError ();
            if (ret != NO_ERROR)
            {
              fprintf (stderr, "lookup next failed\n");
            }
            else
            {
              int i;
              printf ("Got result:\n");
              printf ("  lpszServiceInstanceName: %S\n", result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL");
              if (result->lpServiceClassId)
                printf ("  lpServiceClassId:        { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n",
                    result->lpServiceClassId->Data1, result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, result->lpServiceClassId->Data4[0],
                    result->lpServiceClassId->Data4[1], result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], result->lpServiceClassId->Data4[4],
                    result->lpServiceClassId->Data4[5], result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]);
              else
                printf ("  lpServiceClassId:        NULL\n");
              if (result->lpVersion)
                printf ("  lpVersion:               0x%08lX, %d\n", result->lpVersion->dwVersion, result->lpVersion->ecHow);
              else
                printf ("  lpVersion:               NULL\n");
              printf ("  lpszComment:             %S\n", result->lpszComment ? result->lpszComment : L"NULL");
              printf ("  dwNameSpace:             %lu\n", result->dwNameSpace);
              if (result->lpNSProviderId)
                printf ("  lpNSProviderId:          { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n",
                    result->lpNSProviderId->Data1, result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, result->lpNSProviderId->Data4[0],
                    result->lpNSProviderId->Data4[1], result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], result->lpNSProviderId->Data4[4],
                    result->lpNSProviderId->Data4[5], result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]);
              else
                printf ("  lpNSProviderId:          NULL\n");
              printf ("  lpszContext:             %S\n", result->lpszContext ? result->lpszContext : L"NULL");
              printf ("  dwNumberOfProtocols:     %lu\n", result->dwNumberOfProtocols);
              printf ("  lpszQueryString:         %S\n", result->lpszQueryString ? result->lpszQueryString : L"NULL");
              printf ("  dwNumberOfCsAddrs:       %lu\n", result->dwNumberOfCsAddrs);
              for (i = 0; i < result->dwNumberOfCsAddrs; i++)
              {
                switch (result->lpcsaBuffer[i].iSocketType)
                {
                case SOCK_STREAM:
                  printf ("    %d: iSocketType = SOCK_STREAM\n", i);
                  break;
                case SOCK_DGRAM:
                  printf ("    %d: iSocketType = SOCK_DGRAM\n", i);
                  break;
                default:
                  printf ("    %d: iSocketType = %d\n", i, result->lpcsaBuffer[i].iSocketType);
                }
                switch (result->lpcsaBuffer[i].iProtocol)
                {
                case IPPROTO_TCP:
                  printf ("    %d: iProtocol   = IPPROTO_TCP\n", i);
                  break;
                case IPPROTO_UDP:
                  printf ("    %d: iProtocol   = IPPROTO_UDP\n", i);
                  break;
                default:
                  printf ("    %d: iProtocol   = %d\n", i, result->lpcsaBuffer[i].iProtocol);
                }
                switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family)
                {
                case AF_INET:
                  printf ("    %d: loc family  = AF_INET\n", i);
                  break;
                case AF_INET6:
                  printf ("    %d: loc family  = AF_INET6\n", i);
                  break;
                default:
                  printf ("    %d: loc family  = %hu\n", i, result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family);
                }
                switch (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family)
                {
                case AF_INET:
                  printf ("    %d: rem family  = AF_INET\n", i);
                  break;
                case AF_INET6:
                  printf ("    %d: rem family  = AF_INET6\n", i);
                  break;
                default:
                  printf ("    %d: rem family = %hu\n", i, result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family);
                }
                char buf[1024];
                DWORD buflen = 1024;
                if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].LocalAddr.lpSockaddr, result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen))
                  printf("\tLocal Address #%d: %s\n", i, buf);
                else
                  printf("\tLocal Address #%d: Can't convert: %lu\n", i, GetLastError ());
                buflen = 1024;
                if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen))
                  printf("\tRemote Address #%d: %s\n", i, buf);
                else
                  printf("\tRemote Address #%d: Can't convert: %lu\n", i, GetLastError ());
              }
              printf ("  dwOutputFlags:           0x%08lX\n", result->dwOutputFlags);
              printf ("  lpBlob:                  0x%p\n", result->lpBlob);
              if (result->lpBlob)
              {
                struct hostent *he = malloc (result->lpBlob->cbSize);
                if (he != NULL)
                {
                  memcpy (he, result->lpBlob->pBlobData, result->lpBlob->cbSize);
                  UnpackHostEnt (he);
                  print_hostent (he);
                  free (he);
                }
              }
            }
            ret = api.NSPLookupServiceEnd (lookup);
            if (ret != NO_ERROR)
              printf ("NSPLookupServiceEnd() failed: %lu\n", GetLastError ());
          }
          api.NSPCleanup (prov);
        }
      }
      FreeLibrary (nsp);
    }
  }
  WSACleanup();
  return r;
}