解析對等名稱
本主題討論使用 PNRP 命名空間提供者 API 解析對等名稱的方法。
當您解析對等名稱時,必須提供下列資訊:
解析對等名稱
提供對等名稱、解析準則、雲端名稱和選擇性 IP 位址之後,必須採取下列步驟來完成對等名稱的解析:
- 呼叫 WSALookupServiceBegin 以開始程式並傳回控制碼。
- 呼叫 WSALookupServiceNext 來解析對等名稱。
- 呼叫 WSALookupServiceEnd 以完成程式。
解析對等名稱的範例
下列程式碼片段示範如何解析對等名稱。 範例中有假設會傳回 TCP/IP 位址。
#define UNICODE
#include <initguid.h>
#include <p2p.h>
#pragma comment( lib, "ws2_32.lib")
// 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;
}