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.

350 lines
7.2 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: NetworkAdapterConfig.cpp
  4. //
  5. // Synopsis: Defines a NetworkAdapterConfig
  6. // This object has the knowledge for installing
  7. // using WMI to retrieve network adapter information
  8. //
  9. // History: 02/16/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "NetworkAdapterConfig.h"
  12. #include "NetworkInterface.h"
  13. NetworkAdapterConfig::NetworkAdapterConfig() :
  14. initialized(false),
  15. nicCount(0),
  16. localNICIndex(-1)
  17. {
  18. LOG_CTOR(NetworkAdapterConfig);
  19. }
  20. NetworkAdapterConfig::~NetworkAdapterConfig()
  21. {
  22. LOG_DTOR(NetworkAdapterConfig);
  23. // Free all the NIC info from the vector and reset the count
  24. for (NetworkInterfaceContainer::iterator itr = networkInterfaceContainer.begin();
  25. itr != networkInterfaceContainer.end();
  26. ++itr)
  27. {
  28. if (*itr)
  29. {
  30. delete *itr;
  31. }
  32. }
  33. networkInterfaceContainer.erase(
  34. networkInterfaceContainer.begin(),
  35. networkInterfaceContainer.end());
  36. nicCount = 0;
  37. localNICIndex = 0;
  38. }
  39. HRESULT
  40. NetworkAdapterConfig::Initialize()
  41. {
  42. LOG_FUNCTION(NetworkAdapterConfig::Initialize);
  43. HRESULT hr = S_OK;
  44. PIP_ADAPTER_INFO pInfo = 0;
  45. do
  46. {
  47. DWORD status = 0;
  48. ULONG size = 0;
  49. while (1)
  50. {
  51. status = ::GetAdaptersInfo(pInfo, &size);
  52. if (ERROR_BUFFER_OVERFLOW != status)
  53. {
  54. hr = HRESULT_FROM_WIN32(status);
  55. break;
  56. }
  57. if (pInfo)
  58. {
  59. Win::LocalFree(pInfo);
  60. pInfo = 0;
  61. }
  62. if (0 == size)
  63. {
  64. hr = E_FAIL;
  65. LOG_HRESULT(hr);
  66. return hr;
  67. }
  68. pInfo = (PIP_ADAPTER_INFO) ::LocalAlloc(LPTR, size);
  69. if ( NULL == pInfo )
  70. {
  71. hr = E_OUTOFMEMORY;
  72. LOG_HRESULT(hr);
  73. return hr;
  74. }
  75. }
  76. PIP_ADAPTER_INFO current = pInfo;
  77. while (current)
  78. {
  79. // Create a new network interface based on the adapter info
  80. NetworkInterface* newInterface = new NetworkInterface();
  81. if (!newInterface)
  82. {
  83. LOG(L"Failed to create new interface object");
  84. current = current->Next;
  85. continue;
  86. }
  87. hr = newInterface->Initialize(*current);
  88. if (FAILED(hr))
  89. {
  90. LOG(String::format(
  91. L"Failed to initialize network interface: hr = 0x%1!x!",
  92. hr));
  93. delete newInterface;
  94. current = current->Next;
  95. continue;
  96. }
  97. // Add the new interface to the embedded container
  98. AddInterface(newInterface);
  99. current = current->Next;
  100. }
  101. } while (false);
  102. if (pInfo)
  103. {
  104. HRESULT unused = Win::LocalFree(pInfo);
  105. ASSERT(SUCCEEDED(unused));
  106. }
  107. if (SUCCEEDED(hr))
  108. {
  109. initialized = true;
  110. }
  111. LOG_HRESULT(hr);
  112. return hr;
  113. }
  114. void
  115. NetworkAdapterConfig::AddInterface(NetworkInterface* newInterface)
  116. {
  117. LOG_FUNCTION(NetworkAdapterConfig::AddInterface);
  118. do
  119. {
  120. // verify parameters
  121. if (!newInterface)
  122. {
  123. ASSERT(newInterface);
  124. break;
  125. }
  126. // Add the new NIC to the container and increment the count
  127. networkInterfaceContainer.push_back(newInterface);
  128. ++nicCount;
  129. } while (false);
  130. }
  131. unsigned int
  132. NetworkAdapterConfig::GetNICCount() const
  133. {
  134. LOG_FUNCTION(NetworkAdapterConfig::GetNICCount);
  135. ASSERT(IsInitialized());
  136. LOG(String::format(
  137. L"nicCount = %1!d!",
  138. nicCount));
  139. return nicCount;
  140. }
  141. NetworkInterface*
  142. NetworkAdapterConfig::GetNIC(unsigned int nicIndex)
  143. {
  144. LOG_FUNCTION2(
  145. NetworkAdapterConfig::GetNIC,
  146. String::format(
  147. L"%1!d!",
  148. nicIndex));
  149. ASSERT(IsInitialized());
  150. NetworkInterface* nic = 0;
  151. if (nicIndex < GetNICCount())
  152. {
  153. nic = networkInterfaceContainer[nicIndex];
  154. }
  155. if (!nic)
  156. {
  157. LOG(L"Unable to find NIC");
  158. }
  159. return nic;
  160. }
  161. unsigned int
  162. NetworkAdapterConfig::FindNIC(const String& guid, bool& found) const
  163. {
  164. LOG_FUNCTION2(
  165. NetworkAdapterConfig::FindNIC,
  166. guid.c_str());
  167. unsigned int result = 0;
  168. found = false;
  169. for (unsigned int index = 0;
  170. index < networkInterfaceContainer.size();
  171. ++index)
  172. {
  173. String name = networkInterfaceContainer[index]->GetName();
  174. if (name.icompare(guid) == 0)
  175. {
  176. found = true;
  177. result = index;
  178. break;
  179. }
  180. }
  181. LOG(String::format(
  182. L"result = %1!d!",
  183. result));
  184. return result;
  185. }
  186. NetworkInterface*
  187. NetworkAdapterConfig::GetNICFromName(const String& name, bool& found)
  188. {
  189. LOG_FUNCTION2(
  190. NetworkAdapterConfig::GetNICFromName,
  191. name.c_str());
  192. found = false;
  193. // Default to the first NIC if a match is not found
  194. NetworkInterface* nic = networkInterfaceContainer[FindNIC(name, found)];
  195. if (!nic ||
  196. !found)
  197. {
  198. LOG(L"NIC not found");
  199. }
  200. return nic;
  201. }
  202. void
  203. NetworkAdapterConfig::SetLocalNIC(
  204. const NetworkInterface& nic,
  205. bool setInRegistry)
  206. {
  207. LOG_FUNCTION(NetworkAdapterConfig::SetLocalNIC);
  208. LOG_BOOL(setInRegistry);
  209. SetLocalNIC(nic.GetName(), setInRegistry);
  210. }
  211. void
  212. NetworkAdapterConfig::SetLocalNIC(
  213. String guid,
  214. bool setInRegistry)
  215. {
  216. LOG_FUNCTION2(
  217. NetworkAdapterConfig::SetLocalNIC,
  218. guid.c_str());
  219. LOG_BOOL(setInRegistry);
  220. bool found = false;
  221. localNICIndex = FindNIC(guid, found);
  222. if (found && setInRegistry)
  223. {
  224. ASSERT(networkInterfaceContainer[localNICIndex]);
  225. SetLocalNICInRegistry(*networkInterfaceContainer[localNICIndex]);
  226. }
  227. }
  228. void
  229. NetworkAdapterConfig::SetLocalNICInRegistry(const NetworkInterface& nic)
  230. {
  231. LOG_FUNCTION2(
  232. NetworkAdapterConfig::SetLocalNICInRegistry,
  233. nic.GetName());
  234. // Write the GUID into a regkey so that it can be retrieved
  235. // after reboot
  236. if (!SetRegKeyValue(
  237. CYS_FIRST_DC_REGKEY,
  238. CYS_FIRST_DC_LOCAL_NIC,
  239. nic.GetName(),
  240. HKEY_LOCAL_MACHINE,
  241. true))
  242. {
  243. LOG(L"Failed to set local NIC regkey");
  244. }
  245. }
  246. NetworkInterface*
  247. NetworkAdapterConfig::GetLocalNIC()
  248. {
  249. LOG_FUNCTION(NetworkAdapterConfig::GetLocalNIC);
  250. NetworkInterface* nic = 0;
  251. if (localNICIndex >= 0)
  252. {
  253. nic = networkInterfaceContainer[localNICIndex];
  254. }
  255. else
  256. {
  257. // Since the local NIC hasn't been set, we will
  258. // use the first connected NIC in the list for which
  259. // we failed to obtain an IP lease
  260. for (unsigned int index = 0;
  261. index < networkInterfaceContainer.size();
  262. ++index)
  263. {
  264. nic = networkInterfaceContainer[index];
  265. if (nic &&
  266. nic->IsConnected() &&
  267. !nic->IsDHCPAvailable())
  268. {
  269. break;
  270. }
  271. }
  272. if (nic)
  273. {
  274. SetLocalNIC(*nic, true);
  275. }
  276. }
  277. return nic;
  278. }