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.

337 lines
7.2 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. // REVIEWED-2002/02/26-sburns correct byte count passed.
  91. ::ZeroMemory(buf, tableSize + 1);
  92. PMIB_IPADDRTABLE table = reinterpret_cast<PMIB_IPADDRTABLE>(buf);
  93. LOG(L"Calling GetIpAddrTable");
  94. hr =
  95. Win32ToHresult(
  96. ::GetIpAddrTable(
  97. table,
  98. &tableSize,
  99. FALSE));
  100. BREAK_ON_FAILED_HRESULT2(hr, L"GetIpAddrTable failed");
  101. LOG(String::format(L"dwNumEntries: %1!d!", table->dwNumEntries));
  102. for (DWORD i = 0; i < table->dwNumEntries; ++i)
  103. {
  104. DWORD addr = table->table[i].dwAddr;
  105. LOG(String::format(L"entry %1!d!", i));
  106. LOG(String::format(
  107. L"dwAddr %1!X! (%2!d!.%3!d!.%4!d!.%5!d!)",
  108. addr,
  109. ((BYTE*)&addr)[0],
  110. ((BYTE*)&addr)[1],
  111. ((BYTE*)&addr)[2],
  112. ((BYTE*)&addr)[3]));
  113. // skip loopback, etc.
  114. if (
  115. INADDR_ANY == addr
  116. || INADDR_BROADCAST == addr
  117. || INADDR_LOOPBACK == addr
  118. || 0x0100007f == addr )
  119. {
  120. LOG(L"is loopback/broadcast -- skipping");
  121. continue;
  122. }
  123. // Exclude MCAST addresses (class D).
  124. if (
  125. IN_CLASSA(htonl(addr))
  126. || IN_CLASSB(htonl(addr))
  127. || IN_CLASSC(htonl(addr)) )
  128. {
  129. LOG(L"is class A/B/C");
  130. result = true;
  131. break;
  132. }
  133. LOG(L"not class A/B/C -- skipping");
  134. }
  135. }
  136. while (0);
  137. delete[] buf;
  138. LOG(String::format(L"TCP/IP %1 functioning", result ? L"is" : L"is NOT"));
  139. return result;
  140. }
  141. InstallTcpIpPage::InstallTcpIpPage()
  142. :
  143. DCPromoWizardPage(
  144. IDD_INSTALL_TCPIP,
  145. IDS_INSTALL_TCPIP_PAGE_TITLE,
  146. IDS_INSTALL_TCPIP_PAGE_SUBTITLE)
  147. {
  148. LOG_CTOR(InstallTcpIpPage);
  149. }
  150. InstallTcpIpPage::~InstallTcpIpPage()
  151. {
  152. LOG_DTOR(InstallTcpIpPage);
  153. }
  154. void
  155. InstallTcpIpPage::OnInit()
  156. {
  157. LOG_FUNCTION(InstallTcpIpPage::OnInit);
  158. }
  159. bool
  160. InstallTcpIpPage::OnSetActive()
  161. {
  162. LOG_FUNCTION(InstallTcpIpPage::OnSetActive);
  163. State& state = State::GetInstance();
  164. if (
  165. state.RunHiddenUnattended()
  166. || (IsTcpIpInstalled() && IsTcpIpFunctioning()) )
  167. {
  168. LOG(L"Planning to Skip InstallTcpIpPage");
  169. Wizard& wizard = GetWizard();
  170. if (wizard.IsBacktracking())
  171. {
  172. // backup once again
  173. wizard.Backtrack(hwnd);
  174. return true;
  175. }
  176. int nextPage = Validate();
  177. if (nextPage != -1)
  178. {
  179. LOG(L"skipping InstallTcpIpPage");
  180. wizard.SetNextPageID(hwnd, nextPage);
  181. return true;
  182. }
  183. state.ClearHiddenWhileUnattended();
  184. }
  185. Win::PropSheet_SetWizButtons(
  186. Win::GetParent(hwnd),
  187. PSWIZB_BACK | PSWIZB_NEXT);
  188. return true;
  189. }
  190. bool
  191. InstallTcpIpPage::OnNotify(
  192. HWND /* windowFrom */ ,
  193. UINT_PTR controlIDFrom,
  194. UINT code,
  195. LPARAM /* lParam */ )
  196. {
  197. // LOG_FUNCTION(InstallTcpIpPage::OnNotify);
  198. bool result = false;
  199. if (controlIDFrom == IDC_JUMP)
  200. {
  201. switch (code)
  202. {
  203. case NM_CLICK:
  204. case NM_RETURN:
  205. {
  206. ShowTroubleshooter(hwnd, IDS_INSTALL_TCPIP_HELP_TOPIC);
  207. result = true;
  208. }
  209. default:
  210. {
  211. // do nothing
  212. break;
  213. }
  214. }
  215. }
  216. return result;
  217. }
  218. int
  219. InstallTcpIpPage::Validate()
  220. {
  221. LOG_FUNCTION(InstallTcpIpPage::Validate);
  222. int nextPage = -1;
  223. if (IsTcpIpInstalled() && IsTcpIpFunctioning())
  224. {
  225. State& state = State::GetInstance();
  226. switch (state.GetRunContext())
  227. {
  228. case State::BDC_UPGRADE:
  229. {
  230. ASSERT(state.GetOperation() == State::REPLICA);
  231. nextPage = IDD_REPLICATE_FROM_MEDIA; // IDD_CONFIG_DNS_CLIENT;
  232. break;
  233. }
  234. case State::PDC_UPGRADE:
  235. {
  236. nextPage = IDD_NEW_DOMAIN;
  237. break;
  238. }
  239. case State::NT5_STANDALONE_SERVER:
  240. case State::NT5_MEMBER_SERVER:
  241. {
  242. nextPage = IDD_REPLICA_OR_DOMAIN;
  243. break;
  244. }
  245. default:
  246. {
  247. ASSERT(false);
  248. break;
  249. }
  250. }
  251. }
  252. else
  253. {
  254. String message = String::load(IDS_INSTALL_TCPIP_FIRST);
  255. popup.Info(hwnd, message);
  256. }
  257. return nextPage;
  258. }