Rozwiązywanie nazwy równorzędnej
W tym temacie omówiono metody rozpoznawania nazwy równorzędnej przy użyciu interfejsów API dostawcy przestrzeni nazw PNRP.
Podczas rozpoznawania nazwy równorzędnej należy podać następujące informacje:
- nazwa elementu równorzędnego
- Rozwiązywanie kryteriów
- Nazwa chmury, w której ma zostać rozpoznana nazwa elementu równorzędnego
- Adres IP, który jest opcjonalny i jest używany jako wskazówka
Rozwiązywanie nazwy rówieśniczego
Po podaniu nazwy elementu równorzędnego, rozpoznaniu kryteriów, nazwy chmury i opcjonalnego adresu IP należy wykonać następujące kroki, aby ukończyć rozpoznawanie nazwy elementu równorzędnego:
- Wywołaj WSALookupServiceBegin, aby rozpocząć proces i zwrócić uchwyt.
- Wywołaj WSALookupServiceNext, aby rozpoznać nazwę równorzędną.
- Wywołaj WSALookupServiceEnd, aby ukończyć proces.
Przykład rozpoznawania nazwy elementu równorzędnego
Poniższy fragment kodu przedstawia sposób rozpoznawania nazwy elementu równorzędnego. W przykładzie przyjmuje się założenie, że zostanie zwrócony adres 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;
}