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.

2006 lines
43 KiB

  1. /*
  2. Copyright (c) 1998, Microsoft Corporation, all rights reserved
  3. Description:
  4. The old code is in SaveRegistry and LoadRegistry functions in
  5. ncpa1.1\tcpip\tcpipcpl.cxx
  6. History:
  7. Dec 1997: Vijay Baliga created original version.
  8. */
  9. #include "tcpreg_.h"
  10. /*
  11. Returns:
  12. Number of bytes in the mwsz including the two terminating NULLs.
  13. Notes:
  14. */
  15. DWORD
  16. MwszLength(
  17. IN WCHAR* mwsz
  18. )
  19. {
  20. DWORD dwLength = 2;
  21. RTASSERT(NULL != mwsz);
  22. while (mwsz[0] != 0 || mwsz[1] != 0)
  23. {
  24. dwLength++;
  25. mwsz++;
  26. }
  27. return(dwLength);
  28. }
  29. /*
  30. Returns:
  31. VOID
  32. Notes:
  33. There should be atleast two zeros at the end
  34. */
  35. VOID
  36. ConvertSzToMultiSz(
  37. IN CHAR* sz
  38. )
  39. {
  40. while (TRUE)
  41. {
  42. if ( (0 == sz[0])
  43. && (0 == sz[1]))
  44. {
  45. break;
  46. }
  47. if ( (' ' == sz[0])
  48. || (',' == sz[0]))
  49. {
  50. sz[0] = 0;
  51. }
  52. sz++;
  53. }
  54. }
  55. /*
  56. Returns:
  57. Win32 error code
  58. Notes:
  59. */
  60. DWORD
  61. RegQueryValueWithAllocA(
  62. IN HKEY hKey,
  63. IN CHAR* szValueName,
  64. IN DWORD dwTypeRequired,
  65. IN BYTE** ppbData
  66. )
  67. {
  68. DWORD dwType = 0;
  69. DWORD dwSize = 0;
  70. DWORD dwErr = ERROR_SUCCESS;
  71. RTASSERT(NULL != szValueName);
  72. RTASSERT(NULL != ppbData);
  73. *ppbData = NULL;
  74. dwErr = RegQueryValueExA(hKey,
  75. szValueName,
  76. NULL,
  77. &dwType,
  78. NULL,
  79. &dwSize);
  80. if (ERROR_SUCCESS != dwErr)
  81. {
  82. // TraceHlp("RegQueryValueEx(%s) failed and returned %d.",
  83. // szValueName, dwErr);
  84. goto LDone;
  85. }
  86. if (dwTypeRequired != dwType)
  87. {
  88. dwErr = E_FAIL;
  89. TraceHlp("The type of the value %s should be %d, not %d",
  90. szValueName, dwTypeRequired, dwType);
  91. goto LDone;
  92. }
  93. // For an empty MULTI-SZ, dwSize will be sizeof(CHAR) instead of
  94. // 2 * sizeof(CHAR). We also want to make sure that no matter what
  95. // the type, there will be 2 zeros at the end.
  96. dwSize += 2 * sizeof(CHAR);
  97. *ppbData = LocalAlloc(LPTR, dwSize);
  98. if (NULL == *ppbData)
  99. {
  100. dwErr = GetLastError();
  101. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  102. goto LDone;
  103. }
  104. dwErr = RegQueryValueExA(hKey,
  105. szValueName,
  106. NULL,
  107. &dwType,
  108. *ppbData,
  109. &dwSize);
  110. if (ERROR_SUCCESS != dwErr)
  111. {
  112. // TraceHlp("RegQueryValueEx(%s) failed and returned %d.",
  113. // szValueName, dwErr);
  114. goto LDone;
  115. }
  116. LDone:
  117. if (NO_ERROR != dwErr)
  118. {
  119. LocalFree(*ppbData);
  120. *ppbData = NULL;
  121. }
  122. return(dwErr);
  123. }
  124. /*
  125. Returns:
  126. Win32 error code
  127. Notes:
  128. */
  129. DWORD
  130. RegQueryValueWithAllocW(
  131. IN HKEY hKey,
  132. IN WCHAR* wszValueName,
  133. IN DWORD dwTypeRequired,
  134. IN BYTE** ppbData
  135. )
  136. {
  137. DWORD dwType;
  138. DWORD dwSize;
  139. DWORD dwErr = ERROR_SUCCESS;
  140. RTASSERT(NULL != wszValueName);
  141. RTASSERT(NULL != ppbData);
  142. *ppbData = NULL;
  143. dwErr = RegQueryValueExW(hKey,
  144. wszValueName,
  145. NULL,
  146. &dwType,
  147. NULL,
  148. &dwSize);
  149. if (ERROR_SUCCESS != dwErr)
  150. {
  151. // TraceHlp("RegQueryValueEx(%ws) failed and returned %d.",
  152. // wszValueName, dwErr);
  153. goto LDone;
  154. }
  155. if (dwTypeRequired != dwType)
  156. {
  157. dwErr = E_FAIL;
  158. TraceHlp("The type of the value %ws should be %d, not %d",
  159. wszValueName, dwTypeRequired, dwType);
  160. goto LDone;
  161. }
  162. // For an empty MULTI-SZ, dwSize will be sizeof(WCHAR) instead of
  163. // 2 * sizeof(WCHAR). We also want to make sure that no matter what
  164. // the type, there will be 2 zeros at the end.
  165. dwSize += sizeof(WCHAR);
  166. *ppbData = LocalAlloc(LPTR, dwSize);
  167. if (NULL == *ppbData)
  168. {
  169. dwErr = GetLastError();
  170. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  171. goto LDone;
  172. }
  173. dwErr = RegQueryValueExW(hKey,
  174. wszValueName,
  175. NULL,
  176. &dwType,
  177. *ppbData,
  178. &dwSize);
  179. if (ERROR_SUCCESS != dwErr)
  180. {
  181. // TraceHlp("RegQueryValueEx(%ws) failed and returned %d.",
  182. // wszValueName, dwErr);
  183. goto LDone;
  184. }
  185. LDone:
  186. if (NO_ERROR != dwErr)
  187. {
  188. LocalFree(*ppbData);
  189. *ppbData = NULL;
  190. }
  191. return(dwErr);
  192. }
  193. /*
  194. Returns:
  195. IP address
  196. Notes:
  197. Converts caller's a.b.c.d IP address string to a network byte order IP
  198. address. 0 if formatted incorrectly.
  199. */
  200. IPADDR
  201. IpAddressFromAbcdWsz(
  202. IN WCHAR* wszIpAddress
  203. )
  204. {
  205. CHAR szIpAddress[MAXIPSTRLEN + 1];
  206. IPADDR nboIpAddr;
  207. if (0 == WideCharToMultiByte(
  208. CP_UTF8,
  209. 0,
  210. wszIpAddress,
  211. -1,
  212. szIpAddress,
  213. MAXIPSTRLEN + 1,
  214. NULL,
  215. NULL))
  216. {
  217. return(0);
  218. }
  219. nboIpAddr = inet_addr(szIpAddress);
  220. if (INADDR_NONE == nboIpAddr)
  221. {
  222. nboIpAddr = 0;
  223. }
  224. return(nboIpAddr);
  225. }
  226. /*
  227. Returns:
  228. VOID
  229. Description:
  230. Converts nboIpAddr to a string in the a.b.c.d form and returns same in
  231. caller's szIpAddress buffer. The buffer should be at least
  232. MAXIPSTRLEN + 1 characters long.
  233. */
  234. VOID
  235. AbcdSzFromIpAddress(
  236. IN IPADDR nboIpAddr,
  237. OUT CHAR* szIpAddress
  238. )
  239. {
  240. struct in_addr in_addr;
  241. CHAR* sz;
  242. in_addr.s_addr = nboIpAddr;
  243. sz = inet_ntoa(in_addr);
  244. strcpy(szIpAddress, sz ? sz : "");
  245. }
  246. /*
  247. Returns:
  248. VOID
  249. Description:
  250. Converts nboIpAddr to a string in the a.b.c.d form and returns same in
  251. caller's wszIpAddress buffer. The buffer should be at least
  252. MAXIPSTRLEN + 1 characters long.
  253. */
  254. VOID
  255. AbcdWszFromIpAddress(
  256. IN IPADDR nboIpAddr,
  257. OUT WCHAR* wszIpAddress
  258. )
  259. {
  260. CHAR szIpAddress[MAXIPSTRLEN + 1];
  261. AbcdSzFromIpAddress(nboIpAddr, szIpAddress);
  262. if (0 == MultiByteToWideChar(
  263. CP_UTF8,
  264. 0,
  265. szIpAddress,
  266. -1,
  267. wszIpAddress,
  268. MAXIPSTRLEN + 1))
  269. {
  270. wszIpAddress[0] = 0;
  271. }
  272. }
  273. /*
  274. Returns:
  275. ERROR_SUCCESS: Success (including not finding a.b.c.d)
  276. ERROR_NOT_ENOUGH_MEMORY: Failure
  277. Notes:
  278. Remove the a.b.c.d string wszIpAddress from the space-separated
  279. LocalAlloc'ed list *pwsz. *pwsz is LocalFree'ed and a new string
  280. LocalAlloc'ed and stored in *pwsz.
  281. */
  282. DWORD
  283. RemoveWszIpAddress(
  284. IN WCHAR** pwsz,
  285. IN WCHAR* wszIpAddress
  286. )
  287. {
  288. DWORD cwchIpAddress;
  289. DWORD cwchNew;
  290. WCHAR* wszFound;
  291. WCHAR* wszNew;
  292. DWORD nFoundOffset;
  293. if (NULL == *pwsz)
  294. {
  295. return(ERROR_SUCCESS);
  296. }
  297. cwchIpAddress = wcslen(wszIpAddress);
  298. wszFound = wcsstr(*pwsz, wszIpAddress);
  299. if (!wszFound)
  300. {
  301. return(ERROR_SUCCESS);
  302. }
  303. if (wszFound[cwchIpAddress] == L' ')
  304. {
  305. ++cwchIpAddress;
  306. }
  307. cwchNew = wcslen(*pwsz) - cwchIpAddress + 1;
  308. wszNew = LocalAlloc(LPTR, cwchNew * sizeof(WCHAR));
  309. if (!wszNew)
  310. {
  311. TraceHlp("RemoveWszIpAddress: LocalAlloc returned NULL");
  312. return(ERROR_NOT_ENOUGH_MEMORY);
  313. }
  314. nFoundOffset = (ULONG) (wszFound - *pwsz);
  315. wcsncpy(wszNew, *pwsz, nFoundOffset);
  316. wcscpy(wszNew + nFoundOffset, *pwsz + nFoundOffset + cwchIpAddress);
  317. LocalFree(*pwsz);
  318. *pwsz = wszNew;
  319. return(ERROR_SUCCESS);
  320. }
  321. /*
  322. Returns:
  323. Win32 error code
  324. Notes:
  325. Add the a.b.c.d string wszIpAddress to the front of the space-separated
  326. LocalAlloc'ed list *pwsz. *pwsz is LocalFree'ed and a new string
  327. LocalAlloc'ed and stored in *pwsz.
  328. */
  329. DWORD
  330. PrependWszIpAddress(
  331. IN WCHAR** pwsz,
  332. IN WCHAR* wszIpAddress
  333. )
  334. {
  335. DWORD cwchOld;
  336. DWORD cwchNew;
  337. WCHAR* wszNew;
  338. if (0 == IpAddressFromAbcdWsz(wszIpAddress))
  339. {
  340. TraceHlp("PrependWszIpAddress: Not prepending %ws", wszIpAddress);
  341. return(ERROR_SUCCESS);
  342. }
  343. cwchOld = *pwsz ? wcslen(*pwsz) : 0;
  344. cwchNew = cwchOld + wcslen(wszIpAddress) + 6;
  345. wszNew = LocalAlloc(LPTR, cwchNew * sizeof(WCHAR));
  346. if (!wszNew)
  347. {
  348. TraceHlp("PrependWszIpAddress: LocalAlloc returned NULL");
  349. return(ERROR_NOT_ENOUGH_MEMORY);
  350. }
  351. wcscpy(wszNew, wszIpAddress);
  352. if (cwchOld)
  353. {
  354. wcscat(wszNew, L" ");
  355. wcscat(wszNew, *pwsz);
  356. LocalFree(*pwsz);
  357. }
  358. wcscat(wszNew, L"\0");
  359. *pwsz = wszNew;
  360. return(ERROR_SUCCESS);
  361. }
  362. /*
  363. Returns:
  364. ERROR_SUCCESS: Success (including not finding a.b.c.d)
  365. ERROR_NOT_ENOUGH_MEMORY: Failure
  366. Notes:
  367. Remove the a.b.c.d string wszIpAddress from the LocalAlloc'ed MULTI_SZ
  368. *pmwsz. *pmwsz is LocalFree'ed and a new string LocalAlloc'ed and stored in
  369. *pmwsz.
  370. */
  371. DWORD
  372. RemoveWszIpAddressFromMwsz(
  373. IN WCHAR** pmwsz,
  374. IN WCHAR* wszIpAddress
  375. )
  376. {
  377. DWORD cwchIpAddress;
  378. DWORD cwchNew;
  379. WCHAR* wszFound;
  380. WCHAR* mwszNew;
  381. DWORD nFoundOffset;
  382. if (NULL == *pmwsz)
  383. {
  384. return(ERROR_SUCCESS);
  385. }
  386. cwchIpAddress = wcslen(wszIpAddress);
  387. for (wszFound = *pmwsz;
  388. wszFound[0] != 0;
  389. wszFound += wcslen(wszFound) + 1)
  390. {
  391. if (!wcscmp(wszFound, wszIpAddress))
  392. {
  393. break;
  394. }
  395. }
  396. if (!wszFound[0])
  397. {
  398. return(ERROR_SUCCESS);
  399. }
  400. if (wszFound[cwchIpAddress + 1] != 0)
  401. {
  402. ++cwchIpAddress;
  403. }
  404. cwchNew = MwszLength(*pmwsz) - cwchIpAddress;
  405. mwszNew = LocalAlloc(LPTR, cwchNew * sizeof(WCHAR));
  406. if (!mwszNew)
  407. {
  408. TraceHlp("RemoveWszIpAddress: LocalAlloc returned NULL");
  409. return(ERROR_NOT_ENOUGH_MEMORY);
  410. }
  411. nFoundOffset = (ULONG) (wszFound - *pmwsz);
  412. CopyMemory(mwszNew, *pmwsz, nFoundOffset * sizeof(WCHAR));
  413. CopyMemory(mwszNew + nFoundOffset,
  414. *pmwsz + nFoundOffset + cwchIpAddress,
  415. (cwchNew - nFoundOffset) * sizeof(WCHAR));
  416. LocalFree(*pmwsz);
  417. *pmwsz = mwszNew;
  418. return(ERROR_SUCCESS);
  419. }
  420. /*
  421. Returns:
  422. Win32 error code
  423. Notes:
  424. Add the a.b.c.d string wszIpAddress to the front of the LocalAlloc'ed
  425. MULTI_SZ *pmwsz. *pmwsz is LocalFree'ed and a new string LocalAlloc'ed and
  426. stored in *pmwsz.
  427. */
  428. DWORD
  429. PrependWszIpAddressToMwsz(
  430. IN WCHAR** pmwsz,
  431. IN WCHAR* wszIpAddress
  432. )
  433. {
  434. DWORD cwchIpAddress;
  435. DWORD cwchOld;
  436. DWORD cwchNew;
  437. WCHAR* mwszNew;
  438. cwchIpAddress = wcslen(wszIpAddress);
  439. cwchOld = *pmwsz ? MwszLength(*pmwsz) : 0;
  440. cwchNew = cwchOld + cwchIpAddress + 6;
  441. mwszNew = LocalAlloc(LPTR, cwchNew * sizeof(WCHAR));
  442. if (!mwszNew)
  443. {
  444. TraceHlp("PrependWszIpAddress: LocalAlloc returned NULL");
  445. return(ERROR_NOT_ENOUGH_MEMORY);
  446. }
  447. wcscpy(mwszNew, wszIpAddress);
  448. if (cwchOld)
  449. {
  450. CopyMemory(mwszNew + cwchIpAddress + 1, *pmwsz, cwchOld *sizeof(WCHAR));
  451. LocalFree(*pmwsz);
  452. }
  453. *pmwsz = mwszNew;
  454. return(ERROR_SUCCESS);
  455. }
  456. /*
  457. Returns:
  458. Win32 error code
  459. Notes:
  460. Add the address nboIpAddr to the front of the space-separated
  461. LocalAlloc'ed list *pwsz. *pwsz is LocalFree'ed and a new string
  462. LocalAlloc'ed and stored in *pwsz.
  463. */
  464. DWORD
  465. PrependDwIpAddress(
  466. IN WCHAR** pwsz,
  467. IN IPADDR nboIpAddr
  468. )
  469. {
  470. WCHAR wszIpAddress[MAXIPSTRLEN + 1];
  471. AbcdWszFromIpAddress(nboIpAddr, wszIpAddress);
  472. return(PrependWszIpAddress(pwsz, wszIpAddress));
  473. }
  474. /*
  475. Returns:
  476. Win32 error code
  477. Notes:
  478. Add the address nboIpAddr to the front of the LocalAlloc'ed MULTI_SZ
  479. *pmwsz. *pmwsz is LocalFree'ed and a new string LocalAlloc'ed and stored in
  480. *pmwsz.
  481. */
  482. DWORD
  483. PrependDwIpAddressToMwsz(
  484. IN WCHAR** pmwsz,
  485. IN IPADDR nboIpAddr
  486. )
  487. {
  488. WCHAR wszIpAddress[MAXIPSTRLEN + 1];
  489. AbcdWszFromIpAddress(nboIpAddr, wszIpAddress);
  490. return(PrependWszIpAddressToMwsz(pmwsz, wszIpAddress));
  491. }
  492. /*
  493. Returns:
  494. BOOL
  495. Description:
  496. Returns TRUE if there is any non zero value in pTcpipInfo. It also zeroes
  497. the value.
  498. */
  499. BOOL
  500. FJunkExists(
  501. TCPIP_INFO* pTcpipInfo
  502. )
  503. {
  504. BOOL fRet = FALSE;
  505. if ( 0 != pTcpipInfo->wszIPAddress[0]
  506. && wcscmp(pTcpipInfo->wszIPAddress, WCH_ZEROADDRESS))
  507. {
  508. fRet = TRUE;
  509. pTcpipInfo->fChanged = TRUE;
  510. pTcpipInfo->wszIPAddress[0] = 0;
  511. }
  512. if ( 0 != pTcpipInfo->wszSubnetMask[0]
  513. && wcscmp(pTcpipInfo->wszSubnetMask, WCH_ZEROADDRESS))
  514. {
  515. fRet = TRUE;
  516. pTcpipInfo->fChanged = TRUE;
  517. pTcpipInfo->wszSubnetMask[0] = 0;
  518. }
  519. if ( NULL != pTcpipInfo->wszDNSNameServers
  520. && 0 != pTcpipInfo->wszDNSNameServers[0])
  521. {
  522. fRet = TRUE;
  523. LocalFree(pTcpipInfo->wszDNSNameServers);
  524. pTcpipInfo->wszDNSNameServers = NULL;
  525. }
  526. if ( NULL != pTcpipInfo->mwszNetBIOSNameServers
  527. && 0 != pTcpipInfo->mwszNetBIOSNameServers[0]
  528. && 0 != pTcpipInfo->mwszNetBIOSNameServers[1])
  529. {
  530. fRet = TRUE;
  531. LocalFree(pTcpipInfo->mwszNetBIOSNameServers);
  532. pTcpipInfo->mwszNetBIOSNameServers = NULL;
  533. }
  534. if ( NULL != pTcpipInfo->wszDNSDomainName
  535. && 0 != pTcpipInfo->wszDNSDomainName[0])
  536. {
  537. fRet = TRUE;
  538. LocalFree(pTcpipInfo->wszDNSDomainName);
  539. pTcpipInfo->wszDNSDomainName = NULL;
  540. }
  541. return(fRet);
  542. }
  543. /*
  544. Returns:
  545. VOID
  546. Description:
  547. Clears up the stale information left in the regsitry when we AV or the
  548. machine BS's.
  549. */
  550. VOID
  551. ClearTcpipInfo(
  552. VOID
  553. )
  554. {
  555. LONG lRet;
  556. DWORD dwErr;
  557. HKEY hKeyNdisWanIp = NULL;
  558. WCHAR* mwszAdapters = NULL;
  559. WCHAR* mwszTemp;
  560. WCHAR* wszAdapterName;
  561. TCPIP_INFO* pTcpipInfo = NULL;
  562. DWORD dwPrefixLen = wcslen(WCH_TCPIP_PARAM_INT_W);
  563. DWORD dwStrLen;
  564. lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, REGKEY_TCPIP_NDISWANIP_W, 0,
  565. KEY_READ, &hKeyNdisWanIp);
  566. if (ERROR_SUCCESS != lRet)
  567. {
  568. goto LDone;
  569. }
  570. dwErr = RegQueryValueWithAllocW(hKeyNdisWanIp, REGVAL_IPCONFIG_W,
  571. REG_MULTI_SZ, (BYTE**)&mwszAdapters);
  572. if (NO_ERROR != dwErr)
  573. {
  574. goto LDone;
  575. }
  576. mwszTemp = mwszAdapters;
  577. while (mwszTemp[0] != 0)
  578. {
  579. pTcpipInfo = NULL;
  580. dwStrLen = wcslen(mwszTemp);
  581. if (dwPrefixLen >= dwStrLen)
  582. {
  583. goto LWhileEnd;
  584. }
  585. wszAdapterName = mwszTemp + dwPrefixLen;
  586. RTASSERT('{' == wszAdapterName[0]);
  587. dwErr = LoadTcpipInfo(&pTcpipInfo, wszAdapterName, FALSE);
  588. if (NO_ERROR != dwErr)
  589. {
  590. goto LWhileEnd;
  591. }
  592. if (!FJunkExists(pTcpipInfo))
  593. {
  594. goto LWhileEnd;
  595. }
  596. dwErr = SaveTcpipInfo(pTcpipInfo);
  597. if (NO_ERROR != dwErr)
  598. {
  599. goto LWhileEnd;
  600. }
  601. TraceHlp("Clearing Tcpip info for adapter %ws", wszAdapterName);
  602. dwErr = PDhcpNotifyConfigChange(NULL, wszAdapterName, TRUE, 0,
  603. 0, 0, IgnoreFlag);
  604. LWhileEnd:
  605. if (NULL != pTcpipInfo)
  606. {
  607. FreeTcpipInfo(&pTcpipInfo);
  608. }
  609. mwszTemp = mwszTemp + dwStrLen + 1;
  610. }
  611. LDone:
  612. if (NULL != hKeyNdisWanIp)
  613. {
  614. RegCloseKey(hKeyNdisWanIp);
  615. }
  616. LocalFree(mwszAdapters);
  617. }
  618. /*
  619. Returns:
  620. Win32 error code
  621. Description:
  622. Frees the TCPIP_INFO buffer.
  623. */
  624. DWORD
  625. FreeTcpipInfo(
  626. IN TCPIP_INFO** ppTcpipInfo
  627. )
  628. {
  629. if (NULL == *ppTcpipInfo)
  630. {
  631. return(NO_ERROR);
  632. }
  633. TraceHlp("Freeing Tcpip info for adapter %ws", (*ppTcpipInfo)->wszAdapterName);
  634. LocalFree((*ppTcpipInfo)->wszAdapterName);
  635. LocalFree((*ppTcpipInfo)->mwszNetBIOSNameServers);
  636. LocalFree((*ppTcpipInfo)->wszDNSDomainName);
  637. LocalFree((*ppTcpipInfo)->wszDNSNameServers);
  638. LocalFree(*ppTcpipInfo);
  639. *ppTcpipInfo = NULL;
  640. return(NO_ERROR);
  641. }
  642. /*
  643. Returns:
  644. Win32 error code
  645. Description:
  646. Reads NETBT information for the adapter pTcpipInfo->wszAdapterName from
  647. the registry.
  648. */
  649. DWORD
  650. LoadWinsParam(
  651. IN HKEY hKeyWinsParam,
  652. IN TCPIP_INFO* pTcpipInfo
  653. )
  654. {
  655. HKEY hKeyInterfaces = NULL;
  656. HKEY hKeyInterfaceParam = NULL;
  657. WCHAR* wszNetBtBindPath = NULL;
  658. DWORD dwStrLenTcpip_;
  659. DWORD dwStrLenTcpipBindPath;
  660. DWORD dwErr = ERROR_SUCCESS;
  661. RTASSERT(NULL != pTcpipInfo);
  662. RTASSERT(NULL != pTcpipInfo->wszAdapterName);
  663. RTASSERT(NULL == pTcpipInfo->mwszNetBIOSNameServers);
  664. dwErr = RegOpenKeyExW(hKeyWinsParam,
  665. REGKEY_INTERFACES_W,
  666. 0,
  667. KEY_READ,
  668. &hKeyInterfaces);
  669. if (ERROR_SUCCESS != dwErr)
  670. {
  671. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  672. REGKEY_INTERFACES_W, dwErr);
  673. goto LDone;
  674. }
  675. dwStrLenTcpip_ = wcslen(WCH_TCPIP_);
  676. dwStrLenTcpipBindPath = wcslen(pTcpipInfo->wszAdapterName);
  677. wszNetBtBindPath = LocalAlloc(
  678. LPTR, (dwStrLenTcpip_ + dwStrLenTcpipBindPath + 1) * sizeof(WCHAR));
  679. if (NULL == wszNetBtBindPath)
  680. {
  681. dwErr = GetLastError();
  682. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  683. goto LDone;
  684. }
  685. wcscpy(wszNetBtBindPath, WCH_TCPIP_);
  686. wcscat(wszNetBtBindPath, pTcpipInfo->wszAdapterName);
  687. dwErr = RegOpenKeyExW(hKeyInterfaces,
  688. wszNetBtBindPath,
  689. 0,
  690. KEY_READ,
  691. &hKeyInterfaceParam);
  692. if (ERROR_SUCCESS != dwErr)
  693. {
  694. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  695. wszNetBtBindPath, dwErr);
  696. goto LDone;
  697. }
  698. // Its OK if we cannot find the value. Ignore the error.
  699. RegQueryValueWithAllocW(hKeyInterfaceParam,
  700. REGVAL_NAMESERVERLIST_W,
  701. REG_MULTI_SZ,
  702. (BYTE**)&(pTcpipInfo->mwszNetBIOSNameServers));
  703. LDone:
  704. LocalFree(wszNetBtBindPath);
  705. if (NULL != hKeyInterfaces)
  706. {
  707. RegCloseKey(hKeyInterfaces);
  708. }
  709. if (NULL != hKeyInterfaceParam)
  710. {
  711. RegCloseKey(hKeyInterfaceParam);
  712. }
  713. if (NO_ERROR != dwErr)
  714. {
  715. LocalFree(pTcpipInfo->mwszNetBIOSNameServers);
  716. pTcpipInfo->mwszNetBIOSNameServers = NULL;
  717. }
  718. return(dwErr);
  719. }
  720. /*
  721. Returns:
  722. Win32 error code
  723. Description:
  724. Reads TCPIP information for the adapter pTcpipInfo->wszAdapterName from
  725. the registry.
  726. */
  727. DWORD
  728. LoadTcpipParam(
  729. IN HKEY hKeyTcpipParam,
  730. IN TCPIP_INFO* pTcpipInfo
  731. )
  732. {
  733. HKEY hKeyInterfaces = NULL;
  734. HKEY hKeyInterfaceParam = NULL;
  735. DWORD dwType;
  736. DWORD dwSize;
  737. DWORD dwErr = ERROR_SUCCESS;
  738. RTASSERT(NULL != pTcpipInfo);
  739. RTASSERT(NULL != pTcpipInfo->wszAdapterName);
  740. _wcslwr(pTcpipInfo->wszAdapterName);
  741. RTASSERT(0 == pTcpipInfo->wszIPAddress[0]);
  742. RTASSERT(0 == pTcpipInfo->wszSubnetMask[0]);
  743. RTASSERT(NULL == pTcpipInfo->wszDNSDomainName);
  744. RTASSERT(NULL == pTcpipInfo->wszDNSNameServers);
  745. dwErr = RegOpenKeyExW(hKeyTcpipParam,
  746. REGKEY_INTERFACES_W,
  747. 0,
  748. KEY_READ,
  749. &hKeyInterfaces);
  750. if (ERROR_SUCCESS != dwErr)
  751. {
  752. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  753. REGKEY_INTERFACES_W, dwErr);
  754. goto LDone;
  755. }
  756. // Open subkey for this adapter under "Interfaces"
  757. dwErr = RegOpenKeyExW(hKeyInterfaces,
  758. pTcpipInfo->wszAdapterName,
  759. 0,
  760. KEY_READ,
  761. &hKeyInterfaceParam);
  762. if (ERROR_SUCCESS != dwErr)
  763. {
  764. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  765. pTcpipInfo->wszAdapterName, dwErr);
  766. goto LDone;
  767. }
  768. dwSize = sizeof(pTcpipInfo->wszIPAddress);
  769. // Its OK if we cannot find the value. Ignore the error.
  770. dwErr = RegQueryValueExW(hKeyInterfaceParam,
  771. REGVAL_DHCPIPADDRESS_W,
  772. NULL,
  773. &dwType,
  774. (BYTE*)pTcpipInfo->wszIPAddress,
  775. &dwSize);
  776. if (ERROR_SUCCESS != dwErr || REG_SZ != dwType)
  777. {
  778. dwErr = ERROR_SUCCESS;
  779. RTASSERT(0 == pTcpipInfo->wszIPAddress[0]);
  780. pTcpipInfo->wszIPAddress[0] = 0;
  781. }
  782. dwSize = sizeof(pTcpipInfo->wszSubnetMask);
  783. // Its OK if we cannot find the value. Ignore the error.
  784. dwErr = RegQueryValueExW(hKeyInterfaceParam,
  785. REGVAL_DHCPSUBNETMASK_W,
  786. NULL,
  787. &dwType,
  788. (BYTE*)pTcpipInfo->wszSubnetMask,
  789. &dwSize);
  790. if (ERROR_SUCCESS != dwErr || REG_SZ != dwType)
  791. {
  792. dwErr = ERROR_SUCCESS;
  793. RTASSERT(0 == pTcpipInfo->wszSubnetMask[0]);
  794. pTcpipInfo->wszSubnetMask[0] = 0;
  795. // No point in having a valid IP address with an invalid mask.
  796. pTcpipInfo->wszIPAddress[0] = 0;
  797. }
  798. // Its OK if we cannot find the value. Ignore the error.
  799. RegQueryValueWithAllocW(hKeyInterfaceParam,
  800. REGVAL_DOMAIN_W,
  801. REG_SZ,
  802. (BYTE**)&(pTcpipInfo->wszDNSDomainName));
  803. // Its OK if we cannot find the value. Ignore the error.
  804. RegQueryValueWithAllocW(hKeyInterfaceParam,
  805. REGVAL_NAMESERVER_W,
  806. REG_SZ,
  807. (BYTE**)&(pTcpipInfo->wszDNSNameServers));
  808. LDone:
  809. if (NULL != hKeyInterfaces)
  810. {
  811. RegCloseKey(hKeyInterfaces);
  812. }
  813. if (NULL != hKeyInterfaceParam)
  814. {
  815. RegCloseKey(hKeyInterfaceParam);
  816. }
  817. if (ERROR_SUCCESS != dwErr)
  818. {
  819. LocalFree(pTcpipInfo->wszDNSDomainName);
  820. pTcpipInfo->wszDNSDomainName = NULL;
  821. LocalFree(pTcpipInfo->wszDNSNameServers);
  822. pTcpipInfo->wszDNSNameServers = NULL;
  823. }
  824. return(dwErr);
  825. }
  826. /*
  827. Returns:
  828. Win32 error code
  829. Description:
  830. If fAdapterOnly is FALSE, reads NETBT and TCPIP information for the adapter
  831. wszAdapterName from the registry. *ppTcpipInfo must ultimately be freed by
  832. calling FreeTcpipInfo().
  833. */
  834. DWORD
  835. LoadTcpipInfo(
  836. IN TCPIP_INFO** ppTcpipInfo,
  837. IN WCHAR* wszAdapterName,
  838. IN BOOL fAdapterOnly
  839. )
  840. {
  841. HKEY hKeyTcpipParam = NULL;
  842. HKEY hKeyWinsParam = NULL;
  843. DWORD dwErr = ERROR_SUCCESS;
  844. RTASSERT(NULL != wszAdapterName);
  845. if (NULL == wszAdapterName)
  846. {
  847. dwErr = E_FAIL;
  848. TraceHlp("wszAdapterName is NULL");
  849. goto LDone;
  850. }
  851. *ppTcpipInfo = NULL;
  852. *ppTcpipInfo = LocalAlloc(LPTR, sizeof(TCPIP_INFO));
  853. if (NULL == *ppTcpipInfo)
  854. {
  855. dwErr = GetLastError();
  856. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  857. goto LDone;
  858. }
  859. (*ppTcpipInfo)->wszAdapterName = LocalAlloc(
  860. LPTR, (wcslen(wszAdapterName) + 1) * sizeof(WCHAR));
  861. if (NULL == (*ppTcpipInfo)->wszAdapterName)
  862. {
  863. dwErr = GetLastError();
  864. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  865. goto LDone;
  866. }
  867. wcscpy((*ppTcpipInfo)->wszAdapterName, wszAdapterName);
  868. if (fAdapterOnly)
  869. {
  870. goto LDone;
  871. }
  872. dwErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  873. REGKEY_TCPIP_PARAM_W,
  874. 0,
  875. KEY_READ,
  876. &hKeyTcpipParam);
  877. if (ERROR_SUCCESS != dwErr)
  878. {
  879. if (ERROR_FILE_NOT_FOUND == dwErr)
  880. {
  881. // Mask the error
  882. dwErr = ERROR_SUCCESS;
  883. }
  884. else
  885. {
  886. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  887. REGKEY_TCPIP_PARAM_W, dwErr);
  888. goto LDone;
  889. }
  890. }
  891. else
  892. {
  893. dwErr = LoadTcpipParam(hKeyTcpipParam, *ppTcpipInfo);
  894. if (ERROR_SUCCESS != dwErr)
  895. {
  896. goto LDone;
  897. }
  898. }
  899. // Open NETBT's parameters key
  900. dwErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  901. REGKEY_NETBT_PARAM_W,
  902. 0,
  903. KEY_READ,
  904. &hKeyWinsParam);
  905. if (ERROR_SUCCESS != dwErr)
  906. {
  907. if (ERROR_FILE_NOT_FOUND == dwErr)
  908. {
  909. // Mask the error
  910. dwErr = ERROR_SUCCESS;
  911. }
  912. else
  913. {
  914. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  915. REGKEY_NETBT_PARAM_W, dwErr);
  916. goto LDone;
  917. }
  918. }
  919. else
  920. {
  921. dwErr = LoadWinsParam(hKeyWinsParam, *ppTcpipInfo);
  922. if (ERROR_SUCCESS != dwErr)
  923. {
  924. goto LDone;
  925. }
  926. }
  927. LDone:
  928. if (NULL != hKeyTcpipParam)
  929. {
  930. RegCloseKey(hKeyTcpipParam);
  931. }
  932. if (NULL != hKeyWinsParam)
  933. {
  934. RegCloseKey(hKeyWinsParam);
  935. }
  936. if (ERROR_SUCCESS != dwErr)
  937. {
  938. FreeTcpipInfo(ppTcpipInfo);
  939. }
  940. return(dwErr);
  941. }
  942. /*
  943. Returns:
  944. Win32 error code
  945. Description:
  946. Saves NETBT information for the adapter pTcpipInfo->wszAdapterName to
  947. the registry.
  948. */
  949. DWORD
  950. SaveWinsParam(
  951. IN HKEY hKeyWinsParam,
  952. IN TCPIP_INFO* pTcpipInfo
  953. )
  954. {
  955. HKEY hKeyInterfaces = NULL;
  956. HKEY hKeyInterfaceParam = NULL;
  957. WCHAR* wszNetBtBindPath = NULL;
  958. DWORD dwStrLenTcpip_;
  959. DWORD dwStrLenAdapterName;
  960. WCHAR* mwszData = NULL;
  961. WCHAR mwszBlank[2];
  962. DWORD dw;
  963. DWORD dwErr = ERROR_SUCCESS;
  964. RTASSERT(NULL != pTcpipInfo);
  965. RTASSERT(NULL != pTcpipInfo->wszAdapterName);
  966. dwErr = RegOpenKeyExW(hKeyWinsParam,
  967. REGKEY_INTERFACES_W,
  968. 0,
  969. KEY_WRITE,
  970. &hKeyInterfaces);
  971. if (ERROR_SUCCESS != dwErr)
  972. {
  973. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  974. REGKEY_INTERFACES_W, dwErr);
  975. goto LDone;
  976. }
  977. dwStrLenTcpip_ = wcslen(WCH_TCPIP_);
  978. dwStrLenAdapterName = wcslen(pTcpipInfo->wszAdapterName);
  979. wszNetBtBindPath = LocalAlloc(
  980. LPTR, (dwStrLenTcpip_ + dwStrLenAdapterName + 1) * sizeof(WCHAR));
  981. if (NULL == wszNetBtBindPath)
  982. {
  983. dwErr = GetLastError();
  984. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  985. goto LDone;
  986. }
  987. wcscpy(wszNetBtBindPath, WCH_TCPIP_);
  988. wcscat(wszNetBtBindPath, pTcpipInfo->wszAdapterName);
  989. dwErr = RegOpenKeyExW(hKeyInterfaces,
  990. wszNetBtBindPath,
  991. 0,
  992. KEY_WRITE,
  993. &hKeyInterfaceParam);
  994. if (ERROR_SUCCESS != dwErr)
  995. {
  996. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  997. wszNetBtBindPath, dwErr);
  998. goto LDone;
  999. }
  1000. if (pTcpipInfo->fDisableNetBIOSoverTcpip)
  1001. {
  1002. dw = REGVAL_DISABLE_NETBT;
  1003. dwErr = RegSetValueExW(hKeyInterfaceParam,
  1004. REGVAL_NETBIOSOPTIONS_W,
  1005. 0,
  1006. REG_DWORD,
  1007. (BYTE*)&dw,
  1008. sizeof(DWORD));
  1009. if (ERROR_SUCCESS != dwErr)
  1010. {
  1011. TraceHlp("RegSetValueEx(%ws) failed: %d",
  1012. REGVAL_NETBIOSOPTIONS_W, dwErr);
  1013. dwErr = NO_ERROR; // Ignore this error
  1014. }
  1015. }
  1016. else
  1017. {
  1018. dwErr = RegDeleteValueW(hKeyInterfaceParam, REGVAL_NETBIOSOPTIONS_W);
  1019. if (ERROR_SUCCESS != dwErr)
  1020. {
  1021. TraceHlp("RegDeleteValue(%ws) failed: %d",
  1022. REGVAL_NETBIOSOPTIONS_W, dwErr);
  1023. dwErr = NO_ERROR; // Ignore this error
  1024. }
  1025. }
  1026. if (NULL == pTcpipInfo->mwszNetBIOSNameServers)
  1027. {
  1028. ZeroMemory(mwszBlank, sizeof(mwszBlank));
  1029. mwszData = mwszBlank;
  1030. }
  1031. else
  1032. {
  1033. mwszData = pTcpipInfo->mwszNetBIOSNameServers;
  1034. }
  1035. dwErr = RegSetValueExW(hKeyInterfaceParam,
  1036. REGVAL_NAMESERVERLIST_W,
  1037. 0,
  1038. REG_MULTI_SZ,
  1039. (BYTE*)mwszData,
  1040. sizeof(WCHAR) * MwszLength(mwszData));
  1041. if (ERROR_SUCCESS != dwErr)
  1042. {
  1043. TraceHlp("RegSetValueEx(%ws) failed and returned %d",
  1044. REGVAL_NAMESERVERLIST_W, dwErr);
  1045. goto LDone;
  1046. }
  1047. LDone:
  1048. LocalFree(wszNetBtBindPath);
  1049. if (NULL != hKeyInterfaceParam)
  1050. {
  1051. RegCloseKey(hKeyInterfaceParam);
  1052. }
  1053. if (NULL != hKeyInterfaces)
  1054. {
  1055. RegCloseKey(hKeyInterfaces);
  1056. }
  1057. return(dwErr);
  1058. }
  1059. /*
  1060. Returns:
  1061. Win32 error code
  1062. Description:
  1063. Saves TCPIP information for the adapter pTcpipInfo->wszAdapterName to
  1064. the registry.
  1065. */
  1066. DWORD
  1067. SaveTcpipParam(
  1068. IN HKEY hKeyTcpipParam,
  1069. IN TCPIP_INFO* pTcpipInfo
  1070. )
  1071. {
  1072. HKEY hKeyInterfaces = NULL;
  1073. HKEY hKeyInterfaceParam = NULL;
  1074. DWORD dwLength;
  1075. WCHAR mwszZeroAddress[MAXIPSTRLEN + 1];
  1076. WCHAR* wszData = NULL;
  1077. WCHAR wszBlank[2];
  1078. DWORD dwErr = ERROR_SUCCESS;
  1079. RTASSERT(NULL != pTcpipInfo);
  1080. RTASSERT(NULL != pTcpipInfo->wszAdapterName);
  1081. _wcslwr(pTcpipInfo->wszAdapterName);
  1082. dwErr = RegOpenKeyExW(hKeyTcpipParam,
  1083. REGKEY_INTERFACES_W,
  1084. 0,
  1085. KEY_WRITE,
  1086. &hKeyInterfaces);
  1087. if (ERROR_SUCCESS != dwErr)
  1088. {
  1089. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  1090. REGKEY_INTERFACES_W, dwErr);
  1091. goto LDone;
  1092. }
  1093. // Open subkey for this adapter under "Interfaces"
  1094. dwErr = RegOpenKeyExW(hKeyInterfaces,
  1095. pTcpipInfo->wszAdapterName,
  1096. 0,
  1097. KEY_WRITE,
  1098. &hKeyInterfaceParam);
  1099. if (ERROR_SUCCESS != dwErr)
  1100. {
  1101. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  1102. pTcpipInfo->wszAdapterName, dwErr);
  1103. goto LDone;
  1104. }
  1105. // If fChanged is set
  1106. if (pTcpipInfo->fChanged == TRUE)
  1107. {
  1108. if ( 0 == pTcpipInfo->wszIPAddress[0]
  1109. || 0 == pTcpipInfo->wszSubnetMask[0])
  1110. {
  1111. RTASSERT(wcslen(WCH_ZEROADDRESS) <= MAXIPSTRLEN);
  1112. wcscpy(pTcpipInfo->wszIPAddress, WCH_ZEROADDRESS);
  1113. wcscpy(pTcpipInfo->wszSubnetMask, WCH_ZEROADDRESS);
  1114. }
  1115. dwErr = RegSetValueExW(hKeyInterfaceParam,
  1116. REGVAL_DHCPIPADDRESS_W,
  1117. 0,
  1118. REG_SZ,
  1119. (BYTE*)pTcpipInfo->wszIPAddress,
  1120. sizeof(WCHAR) * wcslen(pTcpipInfo->wszIPAddress));
  1121. if (ERROR_SUCCESS != dwErr)
  1122. {
  1123. TraceHlp("RegSetValueEx(%ws) failed and returned %d",
  1124. REGVAL_DHCPIPADDRESS_W, dwErr);
  1125. goto LDone;
  1126. }
  1127. dwErr = RegSetValueExW(hKeyInterfaceParam,
  1128. REGVAL_DHCPSUBNETMASK_W,
  1129. 0,
  1130. REG_SZ,
  1131. (BYTE*)pTcpipInfo->wszSubnetMask,
  1132. sizeof(WCHAR) *
  1133. wcslen(pTcpipInfo->wszSubnetMask));
  1134. if (ERROR_SUCCESS != dwErr)
  1135. {
  1136. TraceHlp("RegSetValueEx(%ws) failed and returned %d",
  1137. REGVAL_DHCPSUBNETMASK_W, dwErr);
  1138. goto LDone;
  1139. }
  1140. } // if fChanged = TRUE
  1141. ZeroMemory(wszBlank, sizeof(wszBlank));
  1142. if (NULL == pTcpipInfo->wszDNSDomainName)
  1143. {
  1144. wszData = wszBlank;
  1145. }
  1146. else
  1147. {
  1148. wszData = pTcpipInfo->wszDNSDomainName;
  1149. }
  1150. dwErr = RegSetValueExW(hKeyInterfaceParam,
  1151. REGVAL_DOMAIN_W,
  1152. 0,
  1153. REG_SZ,
  1154. (BYTE*)wszData,
  1155. sizeof(WCHAR) * (wcslen(wszData) + 1));
  1156. if (ERROR_SUCCESS != dwErr)
  1157. {
  1158. TraceHlp("RegSetValueEx(%ws) failed and returned %d",
  1159. REGVAL_DOMAIN_W, dwErr);
  1160. goto LDone;
  1161. }
  1162. if (NULL == pTcpipInfo->wszDNSNameServers)
  1163. {
  1164. wszData = wszBlank;
  1165. }
  1166. else
  1167. {
  1168. wszData = pTcpipInfo->wszDNSNameServers;
  1169. }
  1170. // Check whether the value starts with a space.
  1171. // If so, delete the key. Otherwise save the value.
  1172. if (WCH_SPACE != wszData[0])
  1173. {
  1174. dwErr = RegSetValueExW(hKeyInterfaceParam,
  1175. REGVAL_NAMESERVER_W,
  1176. 0,
  1177. REG_SZ,
  1178. (BYTE*)wszData,
  1179. sizeof(WCHAR) * (wcslen(wszData) + 1));
  1180. if (ERROR_SUCCESS != dwErr)
  1181. {
  1182. TraceHlp("RegSetValueEx(%ws) failed and returned %d",
  1183. REGVAL_NAMESERVER_W, dwErr);
  1184. goto LDone;
  1185. }
  1186. }
  1187. else
  1188. {
  1189. dwErr = RegDeleteValueW(hKeyInterfaceParam, REGVAL_NAMESERVER_W);
  1190. if (ERROR_SUCCESS != dwErr)
  1191. {
  1192. TraceHlp("RegDeleteValue(%ws) failed and returned %d",
  1193. REGVAL_NAMESERVER_W, dwErr);
  1194. goto LDone;
  1195. }
  1196. }
  1197. LDone:
  1198. if (NULL != hKeyInterfaceParam)
  1199. {
  1200. RegCloseKey(hKeyInterfaceParam);
  1201. }
  1202. if (NULL != hKeyInterfaces)
  1203. {
  1204. RegCloseKey(hKeyInterfaces);
  1205. }
  1206. return(dwErr);
  1207. }
  1208. /*
  1209. Returns:
  1210. Win32 error code
  1211. Description:
  1212. Saves NETBT and TCPIP information for the adapter
  1213. pTcpipInfo->wszAdapterName to the registry.
  1214. */
  1215. DWORD
  1216. SaveTcpipInfo(
  1217. IN TCPIP_INFO* pTcpipInfo
  1218. )
  1219. {
  1220. HKEY hKeyTcpipParam = NULL;
  1221. HKEY hKeyWinsParam = NULL;
  1222. DWORD dwErr = ERROR_SUCCESS;
  1223. RTASSERT(NULL != pTcpipInfo);
  1224. if ( (NULL == pTcpipInfo)
  1225. || (NULL == pTcpipInfo->wszAdapterName))
  1226. {
  1227. dwErr = E_FAIL;
  1228. TraceHlp("pTcpipInfo or wszAdapterName is NULL");
  1229. goto LDone;
  1230. }
  1231. dwErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  1232. REGKEY_TCPIP_PARAM_W,
  1233. 0,
  1234. KEY_WRITE,
  1235. &hKeyTcpipParam);
  1236. if (ERROR_SUCCESS != dwErr)
  1237. {
  1238. if (ERROR_FILE_NOT_FOUND == dwErr)
  1239. {
  1240. // Mask the error
  1241. dwErr = ERROR_SUCCESS;
  1242. }
  1243. else
  1244. {
  1245. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  1246. REGKEY_TCPIP_PARAM_W, dwErr);
  1247. goto LDone;
  1248. }
  1249. }
  1250. else
  1251. {
  1252. dwErr = SaveTcpipParam(hKeyTcpipParam, pTcpipInfo);
  1253. if (ERROR_SUCCESS != dwErr)
  1254. {
  1255. goto LDone;
  1256. }
  1257. }
  1258. // Open NETBT's parameters key
  1259. dwErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  1260. REGKEY_NETBT_PARAM_W,
  1261. 0,
  1262. KEY_WRITE,
  1263. &hKeyWinsParam);
  1264. if (ERROR_SUCCESS != dwErr)
  1265. {
  1266. if (ERROR_FILE_NOT_FOUND == dwErr)
  1267. {
  1268. // Mask the error
  1269. dwErr = ERROR_SUCCESS;
  1270. }
  1271. else
  1272. {
  1273. TraceHlp("RegOpenKeyEx(%ws) failed and returned %d",
  1274. REGKEY_NETBT_PARAM_W, dwErr);
  1275. goto LDone;
  1276. }
  1277. }
  1278. else
  1279. {
  1280. dwErr = SaveWinsParam(hKeyWinsParam, pTcpipInfo);
  1281. if (ERROR_SUCCESS != dwErr)
  1282. {
  1283. goto LDone;
  1284. }
  1285. }
  1286. LDone:
  1287. if (NULL != hKeyTcpipParam)
  1288. {
  1289. RegCloseKey(hKeyTcpipParam);
  1290. }
  1291. if (NULL != hKeyWinsParam)
  1292. {
  1293. RegCloseKey(hKeyWinsParam);
  1294. }
  1295. return(dwErr);
  1296. }
  1297. /*
  1298. Returns:
  1299. Win32 error code
  1300. Notes:
  1301. */
  1302. DWORD
  1303. GetAdapterInfo(
  1304. IN DWORD dwIndex,
  1305. OUT IPADDR* pnboIpAddress,
  1306. OUT IPADDR* pnboDNS1,
  1307. OUT IPADDR* pnboDNS2,
  1308. OUT IPADDR* pnboWINS1,
  1309. OUT IPADDR* pnboWINS2,
  1310. OUT IPADDR* pnboGateway,
  1311. OUT BYTE* pbAddress
  1312. )
  1313. {
  1314. IP_ADAPTER_INFO* pAdapterInfo = NULL;
  1315. IP_ADAPTER_INFO* pAdapter;
  1316. IP_PER_ADAPTER_INFO* pPerAdapterInfo = NULL;
  1317. DWORD dwSize;
  1318. DWORD dw;
  1319. IPADDR nboIpAddress = 0;
  1320. IPADDR nboDNS1 = 0;
  1321. IPADDR nboDNS2 = 0;
  1322. IPADDR nboWINS1 = 0;
  1323. IPADDR nboWINS2 = 0;
  1324. IPADDR nboGateway = 0;
  1325. BYTE bAddress[MAX_ADAPTER_ADDRESS_LENGTH];
  1326. DWORD dwErr = NO_ERROR;
  1327. TraceHlp("GetAdapterInfo");
  1328. dwSize = 0;
  1329. dwErr = PGetAdaptersInfo(NULL, &dwSize);
  1330. if (ERROR_BUFFER_OVERFLOW != dwErr && NO_ERROR != dwErr )
  1331. {
  1332. TraceHlp("GetAdaptersInfo failed and returned %d", dwErr);
  1333. goto LDone;
  1334. }
  1335. pAdapterInfo = LocalAlloc(LPTR, dwSize);
  1336. if (NULL == pAdapterInfo)
  1337. {
  1338. dwErr = GetLastError();
  1339. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  1340. goto LDone;
  1341. }
  1342. dwErr = PGetAdaptersInfo(pAdapterInfo, &dwSize);
  1343. if (NO_ERROR != dwErr)
  1344. {
  1345. TraceHlp("GetAdaptersInfo failed and returned %d", dwErr);
  1346. goto LDone;
  1347. }
  1348. pAdapter = pAdapterInfo;
  1349. while (pAdapter)
  1350. {
  1351. if (pAdapter->Index != dwIndex)
  1352. {
  1353. pAdapter = pAdapter->Next;
  1354. continue;
  1355. }
  1356. break;
  1357. }
  1358. if (NULL == pAdapter)
  1359. {
  1360. TraceHlp("Couldn't get info for the adapter");
  1361. dwErr = ERROR_NOT_FOUND;
  1362. goto LDone;
  1363. }
  1364. nboIpAddress = inet_addr(pAdapter->IpAddressList.IpAddress.String);
  1365. nboGateway = inet_addr(pAdapter->GatewayList.IpAddress.String);
  1366. if (pAdapter->HaveWins)
  1367. {
  1368. nboWINS1 = inet_addr(pAdapter->PrimaryWinsServer.IpAddress.String);
  1369. nboWINS2 = inet_addr(pAdapter->SecondaryWinsServer.IpAddress.String);
  1370. }
  1371. for (dw = 0;
  1372. dw < pAdapter->AddressLength, dw < MAX_ADAPTER_ADDRESS_LENGTH;
  1373. dw++)
  1374. {
  1375. bAddress[dw] = pAdapter->Address[dw];
  1376. }
  1377. dwSize = 0;
  1378. dwErr = PGetPerAdapterInfo(dwIndex, NULL, &dwSize);
  1379. if (ERROR_BUFFER_OVERFLOW != dwErr)
  1380. {
  1381. TraceHlp("GetPerAdapterInfo failed and returned %d", dwErr);
  1382. goto LDone;
  1383. }
  1384. pPerAdapterInfo = LocalAlloc(LPTR, dwSize);
  1385. if (NULL == pPerAdapterInfo)
  1386. {
  1387. dwErr = GetLastError();
  1388. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  1389. goto LDone;
  1390. }
  1391. dwErr = PGetPerAdapterInfo(dwIndex, pPerAdapterInfo, &dwSize);
  1392. if (NO_ERROR != dwErr)
  1393. {
  1394. TraceHlp("GetPerAdapterInfo failed and returned %d", dwErr);
  1395. goto LDone;
  1396. }
  1397. if (NULL == pPerAdapterInfo)
  1398. {
  1399. TraceHlp("Couldn't get per adapter info for the adapter");
  1400. dwErr = ERROR_NOT_FOUND;
  1401. goto LDone;
  1402. }
  1403. nboDNS1 = inet_addr(pPerAdapterInfo->DnsServerList.IpAddress.String);
  1404. if (NULL != pPerAdapterInfo->DnsServerList.Next)
  1405. {
  1406. nboDNS2 =
  1407. inet_addr(pPerAdapterInfo->DnsServerList.Next->IpAddress.String);
  1408. }
  1409. if ( (0 == nboIpAddress)
  1410. || (INADDR_NONE == nboIpAddress))
  1411. {
  1412. TraceHlp("Couldn't get IpAddress for the adapter");
  1413. dwErr = ERROR_NOT_FOUND;
  1414. goto LDone;
  1415. }
  1416. if(INADDR_NONE == nboGateway)
  1417. {
  1418. nboGateway = 0;
  1419. }
  1420. if (INADDR_NONE == nboDNS1)
  1421. {
  1422. nboDNS1 = 0;
  1423. }
  1424. if (INADDR_NONE == nboDNS2)
  1425. {
  1426. nboDNS2 = 0;
  1427. }
  1428. if (INADDR_NONE == nboWINS1)
  1429. {
  1430. nboWINS1 = 0;
  1431. }
  1432. if (INADDR_NONE == nboWINS2)
  1433. {
  1434. nboWINS2 = 0;
  1435. }
  1436. LDone:
  1437. if (NO_ERROR != dwErr)
  1438. {
  1439. nboIpAddress = nboGateway = nboDNS1 = nboDNS2
  1440. = nboWINS1 = nboWINS2 = 0;
  1441. ZeroMemory(bAddress, MAX_ADAPTER_ADDRESS_LENGTH);
  1442. }
  1443. if (pnboIpAddress)
  1444. {
  1445. *pnboIpAddress = nboIpAddress;
  1446. }
  1447. if (pnboDNS1)
  1448. {
  1449. *pnboDNS1 = nboDNS1;
  1450. }
  1451. if (pnboDNS2)
  1452. {
  1453. *pnboDNS2 = nboDNS2;
  1454. }
  1455. if (pnboWINS1)
  1456. {
  1457. *pnboWINS1 = nboWINS1;
  1458. }
  1459. if (pnboWINS2)
  1460. {
  1461. *pnboWINS2 = nboWINS2;
  1462. }
  1463. if (pbAddress)
  1464. {
  1465. CopyMemory(pbAddress, bAddress, MAX_ADAPTER_ADDRESS_LENGTH);
  1466. }
  1467. if(pnboGateway)
  1468. {
  1469. *pnboGateway = nboGateway;
  1470. }
  1471. LocalFree(pAdapterInfo);
  1472. LocalFree(pPerAdapterInfo);
  1473. return(dwErr);
  1474. }
  1475. /*
  1476. Returns:
  1477. Win32 error code
  1478. Description:
  1479. Don't cache these values because DHCP leases may have expired, etc
  1480. */
  1481. DWORD
  1482. GetPreferredAdapterInfo(
  1483. OUT IPADDR* pnboIpAddress,
  1484. OUT IPADDR* pnboDNS1,
  1485. OUT IPADDR* pnboDNS2,
  1486. OUT IPADDR* pnboWINS1,
  1487. OUT IPADDR* pnboWINS2,
  1488. OUT BYTE* pbAddress
  1489. )
  1490. {
  1491. HANDLE hHeap = NULL;
  1492. IP_INTERFACE_NAME_INFO* pTable = NULL;
  1493. DWORD dw;
  1494. DWORD dwCount;
  1495. DWORD dwIndex = (DWORD)-1;
  1496. DWORD dwErr = NO_ERROR;
  1497. TraceHlp("GetPreferredAdapterInfo");
  1498. hHeap = GetProcessHeap();
  1499. if (NULL == hHeap)
  1500. {
  1501. dwErr = GetLastError();
  1502. TraceHlp("GetProcessHeap failed and returned %d", dwErr);
  1503. goto LDone;
  1504. }
  1505. dwErr = PNhpAllocateAndGetInterfaceInfoFromStack(&pTable, &dwCount,
  1506. FALSE /* bOrder */, hHeap, LPTR);
  1507. if (NO_ERROR != dwErr)
  1508. {
  1509. TraceHlp("NhpAllocateAndGetInterfaceInfoFromStack failed and "
  1510. "returned %d", dwErr);
  1511. goto LDone;
  1512. }
  1513. for (dw = 0; dw < dwCount; dw++)
  1514. {
  1515. // Only interested in NICs
  1516. if (IF_CONNECTION_DEDICATED != pTable[dw].ConnectionType)
  1517. {
  1518. continue;
  1519. }
  1520. // If the admin wants to use a particular NIC
  1521. if ( HelperRegVal.fNICChosen
  1522. && (!IsEqualGUID(&(HelperRegVal.guidChosenNIC),
  1523. &(pTable[dw].DeviceGuid))))
  1524. {
  1525. continue;
  1526. }
  1527. dwIndex = pTable[dw].Index;
  1528. break;
  1529. }
  1530. if ((DWORD)-1 == dwIndex)
  1531. {
  1532. if (HelperRegVal.fNICChosen)
  1533. {
  1534. // The chosen NIC is not available. Let us choose another one.
  1535. for (dw = 0; dw < dwCount; dw++)
  1536. {
  1537. // Only interested in NICs
  1538. if (IF_CONNECTION_DEDICATED != pTable[dw].ConnectionType)
  1539. {
  1540. continue;
  1541. }
  1542. dwIndex = pTable[dw].Index;
  1543. break;
  1544. }
  1545. }
  1546. if ((DWORD)-1 == dwIndex)
  1547. {
  1548. TraceHlp("Couldn't find an appropriate NIC");
  1549. dwErr = ERROR_NOT_FOUND;
  1550. goto LDone;
  1551. }
  1552. HelperRegVal.fNICChosen = FALSE;
  1553. TraceHlp("The network adapter chosen by the administrator is not "
  1554. "available. Some other adapter will be used.");
  1555. }
  1556. dwErr = GetAdapterInfo(
  1557. dwIndex,
  1558. pnboIpAddress,
  1559. pnboDNS1, pnboDNS2,
  1560. pnboWINS1, pnboWINS2,
  1561. NULL,
  1562. pbAddress);
  1563. LDone:
  1564. if (NULL != pTable)
  1565. {
  1566. HeapFree(hHeap, 0, pTable);
  1567. }
  1568. return(dwErr);
  1569. }