Resolving a Peer Name (Windows CE 5.0)

Send Feedback

Resolving a peer name requires the application to provide the following information:

  • Peer name.
  • Resolve criteria.
  • Cloud name in which to resolve the peer name.
  • IP address that is optional and is used as a hint.

Peer Name Resolution Protocol (PNRP) uses Winsock functions to resolve peer names.

To resolve a peer name

  1. Start the name resolution process by calling the WSALookupServiceBegin (Windows Sockets) function to obtain the IP address, port, and protocol for a peer service that is registered on another computer.

    A handle is returned, and must be used when calling WSALookupServiceNext (Windows Sockets). For more information about values to pass in WSALookupServiceBegin parameters, see WSALookupServiceBegin Parameter Values for Resolving Peer Names.

  2. To match the queries specified in the previous call to WSALookupServiceBegin, call the WSALookupServiceNext (Windows Sockets) function.

    The results of this function are determined by the data stored in the WSAQUERYSET (Windows Sockets) structure that was passed in the initial WSALookupServiceBegin function call. For more information about values to pass in WSALookupServiceBegin parameters, see WSALookupServiceNext Parameter Values for Resolving Peer Names.

  3. To complete the name resolution process, call the WSALookupServiceEnd (Windows Sockets) function. Pass the handle obtained from the previous call to WSALookupServiceBegin.

The following code example shows how to resolve a peer name.

//------------------------------------------------------------------------
//Function: PnrpResolve
//Purpose:  Resolve the given name within a PNRP cloud
//Arguments:
//  pwzName  : name to resolve in PNRP, generally the graph ID
//  pwzCloud : name of cloud to resolve in, NULL = global cloud
//  pAddr    : pointer to result buffer
//Returns:  HRESULT
//------------------------------------------------------------------------
HRESULT PnrpResolve(PWSTR pwzName, PWSTR pwzCloud, SOCKADDR_IN6* pAddr)
{
  HRESULT         hr = S_OK;
  PNRPINFO        pnrpInfo = {0};
  BLOB            blPnrpData = {0};
  WSAQUERYSET     querySet = {0};
  WSAQUERYSET*    pResults = NULL;
  WSAQUERYSET     tempResultSet = {0};
  HANDLE          hLookup = NULL;
  BOOL            fFound = FALSE;
  DWORD           dwError;
  INT             iRet;
  ULONG           i;
  DWORD           dwSize = 0;
  // Fill in the WSAQUERYSET.
  pnrpInfo.dwSize = sizeof(pnrpInfo);
  pnrpInfo.nMaxResolve = 1;
  pnrpInfo.dwTimeout = 30;
  pnrpInfo.enResolveCriteria = PNRP_RESOLVE_CRITERIA_NON_CURRENT_PROCESS_PEER_NAME;
  blPnrpData.cbSize = sizeof(pnrpInfo);
  blPnrpData.pBlobData = (BYTE*)&pnrpInfo;
  querySet.dwSize = sizeof(querySet);
  querySet.dwNameSpace = NS_PNRPNAME;
  querySet.lpServiceClassId = (LPGUID)&SVCID_PNRPNAME;
  querySet.lpszServiceInstanceName = pwzName;
  querySet.lpszContext = pwzCloud;
  querySet.lpBlob = &blPnrpData;
  // Start resolve.
  iRet = WSALookupServiceBegin(
  &querySet, LUP_RETURN_NAME | LUP_RETURN_ADDR | LUP_RETURN_COMMENT, &hLookup);
  if (iRet != 0)
  {
    hr = HRESULT_FROM_WIN32(WSAGetLastError());
  }
  if (SUCCEEDED(hr))
  {
    dwSize = sizeof(tempResultSet);
    // Retrieve the required size.
    iRet = WSALookupServiceNext(hLookup, 0, &dwSize, &tempResultSet);
    dwError = WSAGetLastError();
    if (dwError == WSAEFAULT)
    {
      // Allocate space for the results.
      pResults = (WSAQUERYSET*)malloc(dwSize);
      if (pResults == NULL)
      {
        hr = E_OUTOFMEMORY;
      }
    }
    else
    {
      hr = HRESULT_FROM_WIN32(dwError);
    }
  }
  if (SUCCEEDED(hr))
  {
    // Retrieve the addresses.
    iRet = WSALookupServiceNext(hLookup, 0, &dwSize, pResults);
    if (iRet != 0)
    {
      hr = HRESULT_FROM_WIN32(WSAGetLastError());
    }
  }
  if (SUCCEEDED(hr))
  {
    // Return the first IPv6 address found.
    for (i = 0; i < pResults->dwNumberOfCsAddrs; i++)
    {
      if (pResults->lpcsaBuffer[i].iProtocol == IPPROTO_TCP &&
      pResults->lpcsaBuffer[i].RemoteAddr.iSockaddrLength == sizeof(SOCKADDR_IN6))
      {
        CopyMemory(pAddr, pResults->lpcsaBuffer[i].RemoteAddr.lpSockaddr, sizeof(SOCKADDR_IN6));
        fFound = TRUE;
        break;
      }
    }
    if (!fFound)
    {
      // Unable to find an IPv6 address.
      hr = HRESULT_FROM_WIN32(WSA_E_NO_MORE);
    }
  }
  if (hLookup != NULL)
  {
    WSALookupServiceEnd(hLookup);
  }
  if (pResults != NULL)
  {
    free(pResults);
  }
  return hr;
}

See Also

Peer Names and Clouds | Peer-to-Peer Application Development

Send Feedback on this topic to the authors

Feedback FAQs

© 2006 Microsoft Corporation. All rights reserved.