141 lines
3.9 KiB
C++
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;
|
||
|
}
|