Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
4.0 KiB

  1. // NLA.cpp
  2. #include "stdafx.h"
  3. #include "newapi.h"
  4. #include "nla.h"
  5. GUID g_guidNLAServiceClass = NLA_SERVICE_CLASS_GUID;
  6. BOOL _IsSameAdapter(GUID* pGuid, const char* pszAdapter)
  7. {
  8. BOOL fSame = FALSE;
  9. GUID guidAdapter;
  10. if (GUIDFromStringA(pszAdapter, &guidAdapter))
  11. {
  12. fSame = (guidAdapter == *pGuid);
  13. }
  14. return fSame;
  15. }
  16. NLA_BLOB* _NLABlobNext(NLA_BLOB* pnlaBlob)
  17. {
  18. NLA_BLOB* pNext = NULL;
  19. if (pnlaBlob->header.nextOffset)
  20. {
  21. pNext = (NLA_BLOB*) (((BYTE*) pnlaBlob) + pnlaBlob->header.nextOffset);
  22. }
  23. return pNext;
  24. }
  25. int _AllocWSALookupServiceNext(HANDLE hQuery, DWORD dwControlFlags, LPWSAQUERYSET* ppResults)
  26. {
  27. *ppResults = NULL;
  28. DWORD cb = 0;
  29. int error = 0;
  30. if (SOCKET_ERROR == WSALookupServiceNext_NT(hQuery, dwControlFlags, &cb, NULL))
  31. {
  32. error = WSAGetLastError_NT();
  33. if (WSAEFAULT == error)
  34. {
  35. ASSERT(cb);
  36. *ppResults = (LPWSAQUERYSET) LocalAlloc(LPTR, cb);
  37. if (NULL != *ppResults)
  38. {
  39. error = 0;
  40. if (SOCKET_ERROR == WSALookupServiceNext_NT(hQuery, dwControlFlags, &cb, *ppResults))
  41. {
  42. error = WSAGetLastError_NT();
  43. }
  44. }
  45. else
  46. {
  47. error = WSA_NOT_ENOUGH_MEMORY;
  48. }
  49. }
  50. }
  51. // May as well map outdated error code while we're here.
  52. if (WSAENOMORE == error)
  53. {
  54. error = WSA_E_NO_MORE;
  55. }
  56. if (error && (*ppResults))
  57. {
  58. LocalFree(*ppResults);
  59. *ppResults = NULL;
  60. }
  61. return error;
  62. }
  63. NLA_INTERNET GetConnectionInternetType(GUID* pConnectionGuid)
  64. {
  65. NLA_INTERNET ni = NLA_INTERNET_UNKNOWN;
  66. // Init Winsock
  67. WSADATA wsaData;
  68. if (0 == WSAStartup_NT(MAKEWORD(2, 2), &wsaData))
  69. {
  70. // Init query for network names
  71. WSAQUERYSET restrictions = {0};
  72. restrictions.dwSize = sizeof(restrictions);
  73. restrictions.lpServiceClassId = &g_guidNLAServiceClass;
  74. restrictions.dwNameSpace = NS_NLA;
  75. HANDLE hQuery;
  76. // Make sure we do not ask for the (chicken) blobs that take a long time to get
  77. if (0 == WSALookupServiceBegin_NT(&restrictions, LUP_NOCONTAINERS | LUP_DEEP, &hQuery))
  78. {
  79. PWSAQUERYSET pqsResults = NULL;
  80. BOOL fAdapterFound = FALSE;
  81. // Start loop of getting network names
  82. while (!fAdapterFound && (0 == _AllocWSALookupServiceNext(hQuery, 0, &pqsResults)))
  83. {
  84. if (NULL != pqsResults->lpBlob)
  85. {
  86. NLA_BLOB* pnlaBlob = (NLA_BLOB*) pqsResults->lpBlob->pBlobData;
  87. NLA_INTERNET ni2 = NLA_INTERNET_UNKNOWN;
  88. while (NULL != pnlaBlob)
  89. {
  90. switch (pnlaBlob->header.type)
  91. {
  92. case NLA_INTERFACE:
  93. if (_IsSameAdapter(pConnectionGuid, pnlaBlob->data.interfaceData.adapterName))
  94. {
  95. fAdapterFound = TRUE;
  96. }
  97. break;
  98. case NLA_CONNECTIVITY:
  99. ni2 = pnlaBlob->data.connectivity.internet;
  100. break;
  101. default:
  102. break;
  103. }
  104. pnlaBlob = _NLABlobNext(pnlaBlob);
  105. }
  106. if (fAdapterFound)
  107. {
  108. ni = ni2;
  109. }
  110. }
  111. LocalFree(pqsResults);
  112. }
  113. // tidy up and return the result
  114. WSALookupServiceEnd_NT(hQuery);
  115. }
  116. WSACleanup_NT();
  117. }
  118. return ni;
  119. }