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.

333 lines
6.8 KiB

  1. // Copyright (C) 1997 Microsoft Corporation
  2. //
  3. // install tcp/ip page
  4. //
  5. // 12-18-97 sburns
  6. #include "headers.hxx"
  7. #include "InstallTcpIpPage.hpp"
  8. #include "resource.h"
  9. #include "state.hpp"
  10. #include "common.hpp"
  11. // artshel recommends that we use WSAIoctl + SIO_ADDRESS_LIST_QUERY instead of
  12. // GetIpAddrTable because "it's more "official" and less likely to change,
  13. // which means less work for everyone when we upgrade/revise IPHLPAPI," but
  14. // confirms that for Whistler, they are equivalent.
  15. // NTRAID#NTBUG9--2001/04/24-sburns
  16. // sample code:
  17. // //
  18. // // DWORD
  19. // // GetIPv4Addresses(
  20. // // IN LPSOCKET_ADDRESS_LIST *ppList)
  21. // // {
  22. // // LPSOCKET_ADDRESS_LIST pList = NULL;
  23. // // ULONG ulSize = 0;
  24. // // DWORD dwErr;
  25. // // DWORD dwBytesReturned;
  26. // // SOCKET s;
  27. // //
  28. // // *ppList = NULL;
  29. // //
  30. // // s = socket(AF_INET, SOCK_DGRAM, 0);
  31. // // if (s == INVALID_SOCKET)
  32. // // return WSAGetLastError();
  33. // //
  34. // // for (;;) {
  35. // // dwErr = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, pList, ulSize,
  36. // // &dwBytesReturned, NULL, NULL);
  37. // //
  38. // // if (!dwErr) {
  39. // // break;
  40. // // }
  41. // //
  42. // // if (pList) {
  43. // // FREE(pList);
  44. // // pList = NULL;
  45. // // }
  46. // //
  47. // // dwErr = WSAGetLastError();
  48. // // if (dwErr != WSAEFAULT)
  49. // // break;
  50. // //
  51. // // pList = MALLOC(dwBytesReturned);
  52. // // if (!pList) {
  53. // // dwErr = ERROR_NOT_ENOUGH_MEMORY;
  54. // // break;
  55. // // }
  56. // //
  57. // // ulSize = dwBytesReturned;
  58. // // }
  59. // //
  60. // // closesocket(s);
  61. // //
  62. // // *ppList = pList;
  63. // // return dwErr;
  64. // // }
  65. // Returns true if tcp/ip is "working" (can send/receive packets on at least
  66. // one IP address.
  67. bool
  68. IsTcpIpFunctioning()
  69. {
  70. LOG_FUNCTION(IsTcpIpFunctioning);
  71. bool result = false;
  72. // As per nksrin, we will call GetIpAddrTable. If no addresses are in
  73. // the table, then the IP stack is not in a state to send/rcv packets
  74. // with the rest of the world
  75. HRESULT hr = S_OK;
  76. BYTE* buf = 0;
  77. do
  78. {
  79. // first, determine the size of the table
  80. ULONG tableSize = 0;
  81. DWORD err = ::GetIpAddrTable(0, &tableSize, FALSE);
  82. if (err != ERROR_INSUFFICIENT_BUFFER)
  83. {
  84. LOG(L"GetIpAddrTable for table size failed");
  85. LOG_HRESULT(Win32ToHresult(err));
  86. break;
  87. }
  88. // allocate space for the table.
  89. buf = new BYTE[tableSize + 1];
  90. memset(buf, 0, tableSize + 1);
  91. PMIB_IPADDRTABLE table = reinterpret_cast<PMIB_IPADDRTABLE>(buf);
  92. LOG(L"Calling GetIpAddrTable");
  93. hr =
  94. Win32ToHresult(
  95. ::GetIpAddrTable(
  96. table,
  97. &tableSize,
  98. FALSE));
  99. BREAK_ON_FAILED_HRESULT2(hr, L"GetIpAddrTable failed");
  100. LOG(String::format(L"dwNumEntries: %1!d!", table->dwNumEntries));
  101. for (int i = 0; i < table->dwNumEntries; ++i)
  102. {
  103. DWORD addr = table->table[i].dwAddr;
  104. LOG(String::format(L"entry %1!d!", i));
  105. LOG(String::format(
  106. L"dwAddr %1!X! (%2!d!.%3!d!.%4!d!.%5!d!)",
  107. addr,
  108. ((BYTE*)&addr)[0],
  109. ((BYTE*)&addr)[1],
  110. ((BYTE*)&addr)[2],
  111. ((BYTE*)&addr)[3]));
  112. // skip loopback, etc.
  113. if (
  114. INADDR_ANY == addr
  115. || INADDR_BROADCAST == addr
  116. || INADDR_LOOPBACK == addr
  117. || 0x0100007f == addr )
  118. {
  119. LOG(L"is loopback/broadcast -- skipping");
  120. continue;
  121. }
  122. // Exclude MCAST addresses (class D).
  123. if (
  124. IN_CLASSA(htonl(addr))
  125. || IN_CLASSB(htonl(addr))
  126. || IN_CLASSC(htonl(addr)) )
  127. {
  128. LOG(L"is class A/B/C");
  129. result = true;
  130. break;
  131. }
  132. LOG(L"not class A/B/C -- skipping");
  133. }
  134. }
  135. while (0);
  136. delete[] buf;
  137. LOG(String::format(L"TCP/IP %1 functioning", result ? L"is" : L"is NOT"));
  138. return result;
  139. }
  140. InstallTcpIpPage::InstallTcpIpPage()
  141. :
  142. DCPromoWizardPage(
  143. IDD_INSTALL_TCPIP,
  144. IDS_INSTALL_TCPIP_PAGE_TITLE,
  145. IDS_INSTALL_TCPIP_PAGE_SUBTITLE)
  146. {
  147. LOG_CTOR(InstallTcpIpPage);
  148. }
  149. InstallTcpIpPage::~InstallTcpIpPage()
  150. {
  151. LOG_DTOR(InstallTcpIpPage);
  152. }
  153. void
  154. InstallTcpIpPage::OnInit()
  155. {
  156. LOG_FUNCTION(InstallTcpIpPage::OnInit);
  157. }
  158. bool
  159. InstallTcpIpPage::OnSetActive()
  160. {
  161. LOG_FUNCTION(InstallTcpIpPage::OnSetActive);
  162. State& state = State::GetInstance();
  163. if (
  164. state.RunHiddenUnattended()
  165. or (IsTcpIpInstalled() and IsTcpIpFunctioning()) )
  166. {
  167. LOG(L"Planning to Skip InstallTcpIpPage");
  168. Wizard& wizard = GetWizard();
  169. if (wizard.IsBacktracking())
  170. {
  171. // backup once again
  172. wizard.Backtrack(hwnd);
  173. return true;
  174. }
  175. int nextPage = Validate();
  176. if (nextPage != -1)
  177. {
  178. LOG(L"skipping InstallTcpIpPage");
  179. wizard.SetNextPageID(hwnd, nextPage);
  180. return true;
  181. }
  182. state.ClearHiddenWhileUnattended();
  183. }
  184. Win::PropSheet_SetWizButtons(
  185. Win::GetParent(hwnd),
  186. PSWIZB_BACK | PSWIZB_NEXT);
  187. return true;
  188. }
  189. bool
  190. InstallTcpIpPage::OnNotify(
  191. HWND /* windowFrom */ ,
  192. UINT_PTR controlIDFrom,
  193. UINT code,
  194. LPARAM /* lParam */ )
  195. {
  196. // LOG_FUNCTION(InstallTcpIpPage::OnNotify);
  197. bool result = false;
  198. if (controlIDFrom == IDC_JUMP)
  199. {
  200. switch (code)
  201. {
  202. case NM_CLICK:
  203. case NM_RETURN:
  204. {
  205. ShowTroubleshooter(hwnd, IDS_INSTALL_TCPIP_HELP_TOPIC);
  206. result = true;
  207. }
  208. default:
  209. {
  210. // do nothing
  211. break;
  212. }
  213. }
  214. }
  215. return result;
  216. }
  217. int
  218. InstallTcpIpPage::Validate()
  219. {
  220. LOG_FUNCTION(InstallTcpIpPage::Validate);
  221. int nextPage = -1;
  222. if (IsTcpIpInstalled() and IsTcpIpFunctioning())
  223. {
  224. State& state = State::GetInstance();
  225. switch (state.GetRunContext())
  226. {
  227. case State::BDC_UPGRADE:
  228. {
  229. ASSERT(state.GetOperation() == State::REPLICA);
  230. nextPage = IDD_REPLICATE_FROM_MEDIA; // IDD_CONFIG_DNS_CLIENT;
  231. break;
  232. }
  233. case State::PDC_UPGRADE:
  234. {
  235. nextPage = IDD_TREE_OR_CHILD;
  236. break;
  237. }
  238. case State::NT5_STANDALONE_SERVER:
  239. case State::NT5_MEMBER_SERVER:
  240. {
  241. nextPage = IDD_REPLICA_OR_DOMAIN;
  242. break;
  243. }
  244. default:
  245. {
  246. ASSERT(false);
  247. break;
  248. }
  249. }
  250. }
  251. else
  252. {
  253. String message = String::load(IDS_INSTALL_TCPIP_FIRST);
  254. popup.Info(hwnd, message);
  255. }
  256. return nextPage;
  257. }