windows-nt/Source/XPSP1/NT/shell/ext/hnw/wizard/nla.cpp
2020-09-26 16:20:57 +08:00

141 lines
3.9 KiB
C++

// NLA.cpp
#include "stdafx.h"
#include "newapi.h"
#include "nla.h"
GUID g_guidNLAServiceClass = NLA_SERVICE_CLASS_GUID;
BOOL _IsSameAdapter(GUID* pGuid, const char* pszAdapter)
{
BOOL fSame = FALSE;
GUID guidAdapter;
if (GUIDFromStringA(pszAdapter, &guidAdapter))
{
fSame = (guidAdapter == *pGuid);
}
return fSame;
}
NLA_BLOB* _NLABlobNext(NLA_BLOB* pnlaBlob)
{
NLA_BLOB* pNext = NULL;
if (pnlaBlob->header.nextOffset)
{
pNext = (NLA_BLOB*) (((BYTE*) pnlaBlob) + pnlaBlob->header.nextOffset);
}
return pNext;
}
int _AllocWSALookupServiceNext(HANDLE hQuery, DWORD dwControlFlags, LPWSAQUERYSET* ppResults)
{
*ppResults = NULL;
DWORD cb = 0;
int error = 0;
if (SOCKET_ERROR == WSALookupServiceNext_NT(hQuery, dwControlFlags, &cb, NULL))
{
error = WSAGetLastError_NT();
if (WSAEFAULT == error)
{
ASSERT(cb);
*ppResults = (LPWSAQUERYSET) LocalAlloc(LPTR, cb);
if (NULL != *ppResults)
{
error = 0;
if (SOCKET_ERROR == WSALookupServiceNext_NT(hQuery, dwControlFlags, &cb, *ppResults))
{
error = WSAGetLastError_NT();
}
}
else
{
error = WSA_NOT_ENOUGH_MEMORY;
}
}
}
// May as well map outdated error code while we're here.
if (WSAENOMORE == error)
{
error = WSA_E_NO_MORE;
}
if (error && (*ppResults))
{
LocalFree(*ppResults);
*ppResults = NULL;
}
return error;
}
NLA_INTERNET GetConnectionInternetType(GUID* pConnectionGuid)
{
NLA_INTERNET ni = NLA_INTERNET_UNKNOWN;
// Init Winsock
WSADATA wsaData;
if (0 == WSAStartup_NT(MAKEWORD(2, 2), &wsaData))
{
// Init query for network names
WSAQUERYSET restrictions = {0};
restrictions.dwSize = sizeof(restrictions);
restrictions.lpServiceClassId = &g_guidNLAServiceClass;
restrictions.dwNameSpace = NS_NLA;
HANDLE hQuery;
// Make sure we do not ask for the (chicken) blobs that take a long time to get
if (0 == WSALookupServiceBegin_NT(&restrictions, LUP_NOCONTAINERS | LUP_DEEP, &hQuery))
{
PWSAQUERYSET pqsResults = NULL;
BOOL fAdapterFound = FALSE;
// Start loop of getting network names
while (!fAdapterFound && (0 == _AllocWSALookupServiceNext(hQuery, 0, &pqsResults)))
{
if (NULL != pqsResults->lpBlob)
{
NLA_BLOB* pnlaBlob = (NLA_BLOB*) pqsResults->lpBlob->pBlobData;
NLA_INTERNET ni2 = NLA_INTERNET_UNKNOWN;
while (NULL != pnlaBlob)
{
switch (pnlaBlob->header.type)
{
case NLA_INTERFACE:
if (_IsSameAdapter(pConnectionGuid, pnlaBlob->data.interfaceData.adapterName))
{
fAdapterFound = TRUE;
}
break;
case NLA_CONNECTIVITY:
ni2 = pnlaBlob->data.connectivity.internet;
break;
default:
break;
}
pnlaBlob = _NLABlobNext(pnlaBlob);
}
if (fAdapterFound)
{
ni = ni2;
}
}
LocalFree(pqsResults);
}
// tidy up and return the result
WSALookupServiceEnd_NT(hQuery);
}
WSACleanup_NT();
}
return ni;
}