Source code of Windows XP (NT5)
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.

742 lines
31 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: T C P D H C P . C P P
  7. //
  8. // Contents: Functions related to Calling Dhcpcsvc.dll entry point
  9. // called from HrSetMisc
  10. //
  11. // HrNotifyDhcp, HrCallDhcpConfig
  12. //
  13. // Notes: These functions are based on what was in ncpa1.1
  14. //
  15. // HrNotifyDHCP is from CTcpGenPage::NotifyDHCP
  16. // HrCallDhcpConfig is from CallDHCPConfig
  17. //
  18. // Author: tongl 11 May 1997
  19. //
  20. //----------------------------------------------------------------------------
  21. #include "pch.h"
  22. #pragma hdrstop
  23. #include "tcpipobj.h"
  24. #include "ncatlui.h"
  25. #include "ncreg.h"
  26. #include "ncsvc.h"
  27. #include "tcpconst.h"
  28. #include "tcputil.h"
  29. #include "atmcommon.h"
  30. #define ConvertIpDword(dwIpOrSubnet) ((dwIpOrSubnet[3]<<24) | (dwIpOrSubnet[2]<<16) | (dwIpOrSubnet[1]<<8) | (dwIpOrSubnet[0]))
  31. //
  32. // CTcpipcfg::HrNotifyDhcp
  33. //
  34. // Makes on the fly IP Address changes for all cards in the system
  35. //
  36. // hkeyTcpipParam Handle to \CCS\Services\Tcpip\Parameters reg key
  37. HRESULT CTcpipcfg::HrNotifyDhcp()
  38. {
  39. HRESULT hr = S_OK;
  40. HRESULT hrTmp = S_OK;
  41. ADAPTER_INFO* pAdapter;
  42. for (VCARD::iterator iterAdapter = m_vcardAdapterInfo.begin();
  43. iterAdapter != m_vcardAdapterInfo.end();
  44. iterAdapter ++)
  45. {
  46. pAdapter = *iterAdapter;
  47. if((pAdapter->m_BindingState == BINDING_ENABLE) &&
  48. (pAdapter->m_InitialBindingState != BINDING_DISABLE) &&
  49. (!pAdapter->m_fIsWanAdapter))
  50. {
  51. // 1) Static IP-> Dhcp
  52. // The new value is enable DHCP,
  53. // but the old value was disable DHCP
  54. if(pAdapter->m_fEnableDhcp &&
  55. !pAdapter->m_fOldEnableDhcp)
  56. {
  57. TraceTag(ttidTcpip,"[HrNotifyDhcp] adapter:%S: Static IP->DHCP",
  58. pAdapter->m_strBindName.c_str());
  59. HKEY hkeyTcpipParam = NULL;
  60. hrTmp = m_pnccTcpip->OpenParamKey(&hkeyTcpipParam);
  61. if SUCCEEDED(hrTmp)
  62. {
  63. // Enable Dhcp
  64. HKEY hkeyInterfaces = NULL;
  65. DWORD dwGarbage;
  66. // Open the interfaces key
  67. hrTmp = HrRegCreateKeyEx(hkeyTcpipParam,
  68. c_szInterfacesRegKey,
  69. REG_OPTION_NON_VOLATILE,
  70. KEY_READ,
  71. NULL,
  72. &hkeyInterfaces,
  73. &dwGarbage);
  74. if(SUCCEEDED(hrTmp))
  75. {
  76. Assert(hkeyInterfaces);
  77. HKEY hkeyInterfaceParam = NULL;
  78. // Open the interface key for the specified interface
  79. hrTmp = HrRegCreateKeyEx(
  80. hkeyInterfaces,
  81. pAdapter->m_strTcpipBindPath.c_str(),
  82. REG_OPTION_NON_VOLATILE,
  83. KEY_READ_WRITE,
  84. NULL,
  85. &hkeyInterfaceParam,
  86. &dwGarbage);
  87. if (SUCCEEDED(hrTmp))
  88. {
  89. // Clear up the IP address and subnet registry entries
  90. Assert(hkeyInterfaceParam);
  91. hrTmp = HrRegSetString(hkeyInterfaceParam,
  92. RGAS_DHCP_IPADDRESS,
  93. tstring(ZERO_ADDRESS));
  94. if(SUCCEEDED(hrTmp))
  95. {
  96. hrTmp = HrRegSetString(hkeyInterfaceParam,
  97. RGAS_DHCP_SUBNETMASK,
  98. tstring(FF_ADDRESS));
  99. if(SUCCEEDED(hrTmp))
  100. {
  101. // Enable Dhcp & remove first static IP address
  102. hrTmp = HrCallDhcpConfig(
  103. NULL,
  104. (PWSTR)pAdapter->m_strTcpipBindPath.c_str(),
  105. pAdapter->m_guidInstanceId,
  106. FALSE, // static->dhcp
  107. 0, // index
  108. 0, // IP address
  109. 0, // Subnet mask
  110. DhcpEnable); //Flag: enable Dhcp
  111. }
  112. }
  113. }
  114. RegSafeCloseKey(hkeyInterfaceParam);
  115. }
  116. RegSafeCloseKey(hkeyInterfaces);
  117. }
  118. RegSafeCloseKey(hkeyTcpipParam);
  119. }
  120. // 2) Static IP change
  121. // DHCP is disabled now, and also used to be disabled before
  122. if(!pAdapter->m_fEnableDhcp &&
  123. !pAdapter->m_fOldEnableDhcp)
  124. {
  125. TraceTag(ttidTcpip,"[HrNotifyDhcp] adapter:%S: Static IP change.",
  126. pAdapter->m_strBindName.c_str());
  127. HRESULT hrTmp2 = S_OK;
  128. BOOL fStaticIpChanged = FALSE;
  129. // We should have equal number of IP addresses & subnet masks
  130. Assert(pAdapter->m_vstrIpAddresses.size() ==
  131. pAdapter->m_vstrSubnetMask.size());
  132. Assert(pAdapter->m_vstrOldIpAddresses.size() ==
  133. pAdapter->m_vstrOldSubnetMask.size());
  134. // We need to check if individual IP addresses are different
  135. // and call HrCallDhcpConfig once for each difference
  136. int iCountNew = pAdapter->m_vstrIpAddresses.size();
  137. int iCountOld = pAdapter->m_vstrOldIpAddresses.size();
  138. int iCount = iCountNew>iCountOld ? iCountOld :iCountNew;
  139. Assert(iCount>0);
  140. int iIp;
  141. // For each static IP address index in both old and new
  142. // Update IP
  143. for (iIp=0; iIp<iCount; iIp++)
  144. {
  145. // Change address if mismatch
  146. if((*pAdapter->m_vstrIpAddresses[iIp] !=
  147. *pAdapter->m_vstrOldIpAddresses[iIp]) ||
  148. (*pAdapter->m_vstrSubnetMask[iIp] !=
  149. *pAdapter->m_vstrOldSubnetMask[iIp]))
  150. {
  151. // if a mismatch found, change it
  152. fStaticIpChanged = TRUE;
  153. break;
  154. }
  155. }
  156. if (fStaticIpChanged)
  157. {
  158. int i;
  159. // blow away the rest of the old addresses in reverse order
  160. for (i= iCountOld-1; i>=iIp; i--)
  161. {
  162. // Remove IP address on the fly
  163. hrTmp2= HrCallDhcpConfig(
  164. NULL,
  165. (PWSTR)pAdapter->m_strTcpipBindPath.c_str(),
  166. pAdapter->m_guidInstanceId,
  167. TRUE, // IsNewIpAddress: TRUE in static->static
  168. i, // Index of old IP address
  169. 0, // Ip Address: remove
  170. 0, // Subnetmask: remove
  171. IgnoreFlag); // Flag: static->static
  172. TraceError("Ctcpipcfg::HrNotifyDhcp - remove static IP address", hrTmp2);
  173. if SUCCEEDED(hrTmp)
  174. hrTmp = hrTmp2;
  175. }
  176. // add the rest of the new addresses in order
  177. for (i= iIp; i< iCountNew; i++)
  178. {
  179. // Ip Address
  180. DWORD dwIp[4];
  181. GetNodeNum(pAdapter->m_vstrIpAddresses[i]->c_str(),dwIp);
  182. DWORD dwNewIp = ConvertIpDword(dwIp);
  183. // Subnet mask
  184. DWORD dwSubnet[4];
  185. GetNodeNum(pAdapter->m_vstrSubnetMask[i]->c_str(),dwSubnet);
  186. DWORD dwNewSubnet = ConvertIpDword(dwSubnet);
  187. if (0 == i)
  188. {
  189. // $REVIEW(tongl 6/3/98): the first address has to be added differently,
  190. // yet another requirement by the api to change static ip list (bug #180015).
  191. // Bug #180617 had my request to change the API to allow reconfigure whole
  192. // static ip list instead of requiring caller to figure out everything needed
  193. // for the internal data structure change for ip.
  194. // must call "replace" instead of "add"
  195. hrTmp2= HrCallDhcpConfig(
  196. NULL,
  197. (PWSTR)pAdapter->m_strTcpipBindPath.c_str(),
  198. pAdapter->m_guidInstanceId,
  199. TRUE, // IsNewIpAddress: TRUE in static->static
  200. 0, // Replace first address
  201. dwNewIp,
  202. dwNewSubnet,
  203. IgnoreFlag); // Flag: static->static
  204. }
  205. else
  206. {
  207. // Add IP address on the fly
  208. hrTmp2= HrCallDhcpConfig(
  209. NULL,
  210. (PWSTR)pAdapter->m_strTcpipBindPath.c_str(),
  211. pAdapter->m_guidInstanceId,
  212. TRUE, // IsNewIpAddress: TRUE in static->static
  213. 0xFFFF, // New IP address
  214. dwNewIp,
  215. dwNewSubnet,
  216. IgnoreFlag); // Flag: static->static
  217. }
  218. TraceError("Ctcpipcfg::HrNotifyDhcp - add static IP address", hrTmp2);
  219. if SUCCEEDED(hrTmp)
  220. hrTmp = hrTmp2;
  221. }
  222. }
  223. else
  224. {
  225. // existing addresses all match
  226. if (iIp<iCountNew) // We ust get more new addresses to add
  227. {
  228. fStaticIpChanged = TRUE;
  229. while (iIp<iCountNew)
  230. {
  231. DWORD dwIp[4];
  232. Assert(!pAdapter->m_vstrIpAddresses.empty());
  233. GetNodeNum(pAdapter->m_vstrIpAddresses[iIp]->c_str(),
  234. dwIp);
  235. DWORD dwNewIp = ConvertIpDword(dwIp);
  236. // Subnet mask
  237. DWORD dwSubnet[4];
  238. Assert(!pAdapter->m_vstrSubnetMask.empty());
  239. GetNodeNum(pAdapter->m_vstrSubnetMask[iIp]->c_str(),
  240. dwSubnet);
  241. DWORD dwNewSubnet = ConvertIpDword(dwSubnet);
  242. // Add IP address on the fly
  243. hrTmp2= HrCallDhcpConfig(
  244. NULL,
  245. (PWSTR)pAdapter->m_strTcpipBindPath.c_str(),
  246. pAdapter->m_guidInstanceId,
  247. TRUE, // IsNewIpAddress: TRUE in static->static
  248. 0xFFFF, // New IP address
  249. dwNewIp,
  250. dwNewSubnet,
  251. IgnoreFlag); // Flag: static->static
  252. TraceError("Ctcpipcfg::HrNotifyDhcp - add static IP address", hrTmp2);
  253. if SUCCEEDED(hrTmp)
  254. hrTmp = hrTmp2;
  255. iIp++;
  256. }
  257. }
  258. else if (iIp<iCountOld) // We just get more old addresses to remove
  259. {
  260. fStaticIpChanged = TRUE;
  261. int iIp2 = iCountOld-1;
  262. while (iIp2 >= iIp)
  263. {
  264. // Remove IP address on the fly
  265. hrTmp2= HrCallDhcpConfig(
  266. NULL,
  267. (PWSTR)pAdapter->m_strTcpipBindPath.c_str(),
  268. pAdapter->m_guidInstanceId,
  269. TRUE, // IsNewIpAddress: TRUE in static->static
  270. iIp2, // Index of old IP address
  271. 0, // Ip Address: remove
  272. 0, // Subnetmask: remove
  273. IgnoreFlag); // Flag: static->static
  274. TraceError("Ctcpipcfg::HrNotifyDhcp - remove static IP address", hrTmp2);
  275. if SUCCEEDED(hrTmp)
  276. hrTmp = hrTmp2;
  277. iIp2--;
  278. }
  279. }
  280. }
  281. }
  282. // 3) Dhcp->Static
  283. // DHCP is disabled now, but used to be enabled
  284. if(!pAdapter->m_fEnableDhcp &&
  285. pAdapter->m_fOldEnableDhcp)
  286. {
  287. TraceTag(ttidTcpip,"[HrNotifyDhcp] adapter:%S: DHCP->Static IP",
  288. pAdapter->m_strBindName.c_str());
  289. // Disable Dhcp & add first static Ip address
  290. Assert(!pAdapter->m_vstrIpAddresses.empty());
  291. // Ip Address
  292. DWORD dwIp[4];
  293. GetNodeNum(pAdapter->m_vstrIpAddresses[0]->c_str(),
  294. dwIp);
  295. DWORD dwNewIp = ConvertIpDword(dwIp);
  296. // Subnet Mask
  297. DWORD dwSubnet[4];
  298. Assert(!pAdapter->m_vstrSubnetMask.empty());
  299. GetNodeNum(pAdapter->m_vstrSubnetMask[0]->c_str(),
  300. dwSubnet);
  301. DWORD dwNewSubnet = ConvertIpDword(dwSubnet);
  302. // change IP address on the fly
  303. hrTmp = HrCallDhcpConfig(
  304. NULL,
  305. (PWSTR)pAdapter->m_strTcpipBindPath.c_str(),
  306. pAdapter->m_guidInstanceId,
  307. TRUE,
  308. 0, // index: update dhcp address to first static address
  309. dwNewIp,
  310. dwNewSubnet,
  311. DhcpDisable); // Flag: disable Dhcp
  312. if SUCCEEDED(hrTmp)
  313. {
  314. HRESULT hrTmp2 = S_OK;
  315. // Add the rest of new static IP addresses
  316. for (size_t iIp = 1;
  317. iIp < pAdapter->m_vstrIpAddresses.size();
  318. iIp++)
  319. {
  320. // Ip Address
  321. DWORD dwIp[4];
  322. Assert(!pAdapter->m_vstrIpAddresses.empty());
  323. GetNodeNum(pAdapter->m_vstrIpAddresses[iIp]->c_str(),
  324. dwIp);
  325. DWORD dwNewIp = ConvertIpDword(dwIp);
  326. // Subnet Mask
  327. DWORD dwSubnet[4];
  328. Assert(!pAdapter->m_vstrSubnetMask.empty());
  329. GetNodeNum(pAdapter->m_vstrSubnetMask[iIp]->c_str(),
  330. dwSubnet);
  331. DWORD dwNewSubnet = ConvertIpDword(dwSubnet);
  332. // change IP address on the fly
  333. hrTmp2= HrCallDhcpConfig(
  334. NULL,
  335. (PWSTR)pAdapter->m_strTcpipBindPath.c_str(),
  336. pAdapter->m_guidInstanceId,
  337. TRUE,
  338. 0xFFFF, // index: new address
  339. dwNewIp,
  340. dwNewSubnet,
  341. IgnoreFlag ); // Flag: static->static
  342. TraceError("CTcpipcfg::HrNotifyDhcp - add static IP address", hrTmp2);
  343. if SUCCEEDED(hrTmp)
  344. hrTmp = hrTmp2;
  345. }
  346. }
  347. }
  348. if (SUCCEEDED(hr))
  349. hr = hrTmp;
  350. // 4) Dhcp Class ID, DNS server list and domain change
  351. // $REVIEW(tongl 6/12): Notify DNS server list and domain changes
  352. // here (Raid #175766)
  353. DHCP_PNP_CHANGE DhcpPnpChange;
  354. ZeroMemory(&DhcpPnpChange, sizeof(DHCP_PNP_CHANGE));
  355. DhcpPnpChange.Version = DHCP_PNP_CHANGE_VERSION_0;
  356. DhcpPnpChange.HostNameChanged = FALSE;
  357. DhcpPnpChange.MaskChanged = FALSE;
  358. //Bug 257868 If there is user specified default gateway, notify dhcp client
  359. DhcpPnpChange.GateWayChanged = !fIsSameVstr(pAdapter->m_vstrDefaultGateway,
  360. pAdapter->m_vstrOldDefaultGateway) ||
  361. !fIsSameVstr(pAdapter->m_vstrDefaultGatewayMetric,
  362. pAdapter->m_vstrOldDefaultGatewayMetric);
  363. DhcpPnpChange.RouteChanged = FALSE;
  364. DhcpPnpChange.OptsChanged = FALSE;
  365. DhcpPnpChange.OptDefsChanged = FALSE;
  366. DhcpPnpChange.DnsListChanged = !fIsSameVstr(pAdapter->m_vstrDnsServerList,
  367. pAdapter->m_vstrOldDnsServerList);
  368. DhcpPnpChange.DomainChanged = pAdapter->m_strDnsDomain != pAdapter->m_strOldDnsDomain;
  369. DhcpPnpChange.ClassIdChanged = FALSE;
  370. DhcpPnpChange.DnsOptionsChanged =
  371. ((!!pAdapter->m_fDisableDynamicUpdate) !=
  372. (!!pAdapter->m_fOldDisableDynamicUpdate))
  373. ||
  374. ((!!pAdapter->m_fEnableNameRegistration) !=
  375. (!!pAdapter->m_fOldEnableNameRegistration));
  376. if(DhcpPnpChange.DnsListChanged ||
  377. DhcpPnpChange.DnsOptionsChanged ||
  378. DhcpPnpChange.DomainChanged ||
  379. (DhcpPnpChange.GateWayChanged && pAdapter->m_fEnableDhcp))
  380. {
  381. hrTmp = HrCallDhcpHandlePnPEvent(pAdapter, &DhcpPnpChange);
  382. if (FAILED(hrTmp))
  383. {
  384. TraceError("HrCallDhcpHandlePnPEvent returns failure, requesting reboot...", hrTmp);
  385. hr = NETCFG_S_REBOOT;
  386. }
  387. }
  388. if (pAdapter->m_fBackUpSettingChanged)
  389. {
  390. hrTmp = HrDhcpRefreshFallbackParams(pAdapter);
  391. if (FAILED(hrTmp))
  392. {
  393. TraceError("HrDhcpRefreshFallbackParams returns failure, requesting reboot...", hrTmp);
  394. hr = NETCFG_S_REBOOT;
  395. }
  396. }
  397. }
  398. }
  399. if (NETCFG_S_REBOOT != hr)
  400. hr = hrTmp;
  401. TraceError("CTcpipcfg::HrNotifyDhcp", hr);
  402. return hr;
  403. }
  404. // Define the export function prototype from dhcpcsvc.dll
  405. typedef DWORD (APIENTRY *T_DhcpNotifyConfigChange)(PWSTR ServerName,
  406. PWSTR AdapterName,
  407. BOOL IsNewIpAddress,
  408. DWORD IpIndex,
  409. DWORD IpAddress,
  410. DWORD SubnetMask,
  411. SERVICE_ENABLE DhcpServiceEnabled);
  412. //
  413. // CTcpipcfg::HrCallDhcpConfig
  414. //
  415. // Sets the IP address on the fly (without re-booting)
  416. //
  417. // ServerName always set to NULL
  418. // AdapterName the adapter BindPathName to tcpip
  419. // IsNewIpAddress set to TRUE if Dhcp->Static or Statis->Static changes
  420. // set to FALSE if Static->Dhcp changes
  421. //
  422. //
  423. // IpIndex the index of the IP Address for the card
  424. // adapters can have more than 1 IP Address
  425. // (as seen in the Advanced dialog)
  426. // (this is causing problem for Munil
  427. // because the use of this index is buggy in his code
  428. // index is always set to 0 if there is only one IP Address
  429. // for the card
  430. //
  431. // IpAddress the new IP Address
  432. // SubnetMask the new SubnetMask
  433. //
  434. // DhcpServiceEnabled enum type, can be set to :
  435. // DhcpEnable -> if DHCP was disabled,
  436. // but now being changed to enabled
  437. // IgnoreFlag -> DHCP was disabled and is still disabled
  438. // DhcpDisable -> DHCP was enabled, but now being changed
  439. // to disabled
  440. //
  441. // For extra reference talk to Munil -> these parameters correspond to the
  442. // DhcpNotifyConfigChange API of the dhcpcsvc.dll file
  443. //
  444. HRESULT CTcpipcfg::HrCallDhcpConfig(PWSTR ServerName,
  445. PWSTR AdapterName,
  446. GUID & guidAdaputer,
  447. BOOL IsNewIpAddress,
  448. DWORD IpIndex,
  449. DWORD IpAddress,
  450. DWORD SubnetMask,
  451. SERVICE_ENABLE DhcpServiceEnabled)
  452. {
  453. HRESULT hr = S_OK;
  454. // Make sure TCP/IP is running.
  455. // Scoping brackets cause service and service controller to be
  456. // closed when we don't need them anymore.
  457. {
  458. CServiceManager smng;
  459. CService serv;
  460. hr = smng.HrOpenService(&serv, c_szTcpip, NO_LOCK,
  461. SC_MANAGER_CONNECT, SERVICE_QUERY_STATUS);
  462. if(SUCCEEDED(hr))
  463. {
  464. DWORD dwState;
  465. hr = serv.HrQueryState(&dwState);
  466. if(SUCCEEDED(hr))
  467. {
  468. if(dwState != SERVICE_RUNNING)
  469. {
  470. //TCPIP must always be running if installed!!!
  471. AssertSz(FALSE, "Tcpip service must always be running if installed!");
  472. hr = E_FAIL;
  473. }
  474. }
  475. }
  476. }
  477. if (SUCCEEDED(hr))
  478. {
  479. HMODULE hDll;
  480. FARPROC pDhcpConfig;
  481. hr = HrLoadLibAndGetProc (L"dhcpcsvc.dll",
  482. "DhcpNotifyConfigChange",
  483. &hDll, &pDhcpConfig);
  484. if (SUCCEEDED(hr))
  485. {
  486. TraceTag(ttidTcpip,"Begin calling DhcpNotifyConfigChange...");
  487. // Parameter dump for debugging
  488. TraceTag(ttidTcpip, "[DhcpNotifyConfigChange] ServerName:%S", ServerName);
  489. TraceTag(ttidTcpip, "[DhcpNotifyConfigChange] AdapterName:%S", AdapterName);
  490. TraceTag(ttidTcpip, "[DhcpNotifyConfigChange] IsNewIpAddress:%d", IsNewIpAddress);
  491. TraceTag(ttidTcpip, "[DhcpNotifyConfigChange] IpIndex:%d", IpIndex);
  492. TraceTag(ttidTcpip, "[DhcpNotifyConfigChange] IpAddress:%d", IpAddress);
  493. TraceTag(ttidTcpip, "[DhcpNotifyConfigChange] SubnetMask:%d", SubnetMask);
  494. TraceTag(ttidTcpip, "[DhcpNotifyConfigChange] DhcpServiceEnabled:%d", DhcpServiceEnabled);
  495. DWORD dwError;
  496. dwError = (*(T_DhcpNotifyConfigChange)pDhcpConfig)(
  497. ServerName,
  498. AdapterName,
  499. IsNewIpAddress,
  500. IpIndex,
  501. IpAddress,
  502. SubnetMask,
  503. DhcpServiceEnabled);
  504. TraceTag(ttidTcpip,"Finished calling DhcpNotifyConfigChange...");
  505. hr = HRESULT_FROM_WIN32(dwError);
  506. if FAILED(hr)
  507. {
  508. // Added as part of fix for #107373
  509. if (ERROR_DUP_NAME == dwError)
  510. {
  511. // Warn the user about duplicate IP address
  512. NcMsgBox(::GetActiveWindow(), IDS_MSFT_TCP_TEXT,
  513. IDS_DUP_NETIP, MB_APPLMODAL | MB_ICONEXCLAMATION | MB_OK);
  514. hr = S_OK;
  515. }
  516. else if (ERROR_FILE_NOT_FOUND == dwError)
  517. {
  518. // The adapter we want to reconfig is not connected
  519. TraceTag(ttidTcpip, "The adater is disconnected or not bound to TCP/IP.");
  520. hr = S_OK;
  521. }
  522. else if (STATUS_DUPLICATE_OBJECTID == dwError)
  523. {
  524. // fix for 320797
  525. TraceTag(ttidTcpip, "The address is already configured for the adapter");
  526. hr = S_OK;
  527. }
  528. else if (ERROR_INVALID_DRIVE == dwError)
  529. {
  530. // fix for 320797
  531. TraceTag(ttidTcpip, "The address has already been deleted from the stack");
  532. hr = S_OK;
  533. }
  534. else
  535. {
  536. TraceError("Error on DhcpNotifyConfigChange from dhcpcsvc.dll", hr);
  537. FARPROC pfnHrGetPnpDeviceStatus = NULL;
  538. HRESULT hrTmp = S_OK;
  539. HMODULE hNetman = NULL;
  540. NETCON_STATUS ncStatus = NCS_CONNECTED;
  541. hrTmp = HrLoadLibAndGetProc(L"netman.dll", "HrGetPnpDeviceStatus",
  542. &hNetman, &pfnHrGetPnpDeviceStatus);
  543. if (SUCCEEDED(hrTmp))
  544. {
  545. Assert(pfnHrGetPnpDeviceStatus);
  546. hrTmp = (*(PHRGETPNPDEVICESTATUS)pfnHrGetPnpDeviceStatus)(
  547. &guidAdaputer,
  548. &ncStatus);
  549. FreeLibrary(hNetman);
  550. }
  551. if (SUCCEEDED(hrTmp) && NCS_MEDIA_DISCONNECTED == ncStatus)
  552. {
  553. TraceTag(ttidTcpip, "The connection is media disconnected. Do not need to reboot");
  554. hr = S_OK;
  555. }
  556. else
  557. {
  558. // Mask the specific error so NCPA does not fail.
  559. hr = NETCFG_S_REBOOT;
  560. }
  561. }
  562. }
  563. FreeLibrary (hDll);
  564. }
  565. }
  566. TraceError("CTcpipcfg::HrCallDhcpConfig", hr);
  567. return hr;
  568. }
  569. typedef DWORD (WINAPI * PFNDhcpHandlePnPEvent) (
  570. IN DWORD Flags,
  571. IN DWORD Caller,
  572. IN PWSTR AdapterName,
  573. IN LPDHCP_PNP_CHANGE Changes,
  574. IN LPVOID Reserved
  575. );
  576. HRESULT CTcpipcfg::HrCallDhcpHandlePnPEvent(ADAPTER_INFO * pAdapterInfo,
  577. LPDHCP_PNP_CHANGE pDhcpPnpChange)
  578. {
  579. // load the dll and get function pointer
  580. HMODULE hDll;
  581. FARPROC pDhcpHandlePnPEvent;
  582. HRESULT hr = HrLoadLibAndGetProc (L"dhcpcsvc.dll",
  583. "DhcpHandlePnPEvent",
  584. &hDll, &pDhcpHandlePnPEvent);
  585. if (SUCCEEDED(hr))
  586. {
  587. TraceTag(ttidTcpip, "[DhcpHandlePnPEvent] Flags: 0");
  588. TraceTag(ttidTcpip, "[DhcpHandlePnPEvent] Caller: DHCP_CALLER_TCPUI");
  589. TraceTag(ttidTcpip, "[DhcpHandlePnPEvent] AdapterName: %S", pAdapterInfo->m_strBindName.c_str());
  590. TraceTag(ttidTcpip, "[DhcpHandlePnPEvent] Changes.DnsListChanged: %d", pDhcpPnpChange->DnsListChanged);
  591. TraceTag(ttidTcpip, "[DhcpHandlePnPEvent] Changes.DomainChanged: %d", pDhcpPnpChange->DomainChanged);
  592. TraceTag(ttidTcpip, "[DhcpHandlePnPEvent] Changes.ClassIdChanged: %d", pDhcpPnpChange->ClassIdChanged);
  593. DWORD dwRet = (*(PFNDhcpHandlePnPEvent)pDhcpHandlePnPEvent)(
  594. 0,
  595. DHCP_CALLER_TCPUI,
  596. (PWSTR)pAdapterInfo->m_strBindName.c_str(),
  597. pDhcpPnpChange,
  598. NULL);
  599. hr = HRESULT_FROM_WIN32(dwRet);
  600. if (ERROR_FILE_NOT_FOUND == dwRet)
  601. {
  602. // The adapter we want to reconfig is not connected
  603. TraceTag(ttidTcpip, "DhcpHandlePnPEvent returns ERROR_FILE_NOT_FOUND. The adater is disconnected or not bound to TCP/IP.");
  604. hr = S_OK;
  605. }
  606. FreeLibrary (hDll);
  607. }
  608. TraceError("CTcpipcfg::HrCallDhcpHandlePnPEvent", hr);
  609. return hr;
  610. }
  611. typedef DWORD (WINAPI * PFDhcpFallbackRefreshParams) (
  612. IN LPWSTR AdapterName
  613. );
  614. HRESULT CTcpipcfg::HrDhcpRefreshFallbackParams(ADAPTER_INFO * pAdapterInfo)
  615. {
  616. // load the dll and get function pointer
  617. HMODULE hDll;
  618. FARPROC pDhcpFallbackRefreshParams;
  619. HRESULT hr = HrLoadLibAndGetProc (L"dhcpcsvc.dll",
  620. "DhcpFallbackRefreshParams",
  621. &hDll, &pDhcpFallbackRefreshParams);
  622. if (SUCCEEDED(hr))
  623. {
  624. TraceTag(ttidTcpip, "[DhcpFallbackRefreshParams] AdapterName: %S", pAdapterInfo->m_strBindName.c_str());
  625. DWORD dwRet = (*(PFDhcpFallbackRefreshParams)pDhcpFallbackRefreshParams)(
  626. (LPWSTR)pAdapterInfo->m_strBindName.c_str()
  627. );
  628. hr = HRESULT_FROM_WIN32(dwRet);
  629. if (ERROR_FILE_NOT_FOUND == dwRet)
  630. {
  631. // The adapter we want to reconfig is not connected
  632. TraceTag(ttidTcpip, "DhcpFallbackRefreshParams returns ERROR_FILE_NOT_FOUND. The adater is disconnected or not bound to TCP/IP.");
  633. hr = S_OK;
  634. }
  635. FreeLibrary (hDll);
  636. }
  637. TraceError("CTcpipcfg::HrDhcpRefreshFallbackParams", hr);
  638. return hr;
  639. }