|
|
// Copyright (C) 1997 Microsoft Corporation
//
// install tcp/ip page
//
// 12-18-97 sburns
#include "headers.hxx"
#include "InstallTcpIpPage.hpp"
#include "resource.h"
#include "state.hpp"
#include "common.hpp"
// artshel recommends that we use WSAIoctl + SIO_ADDRESS_LIST_QUERY instead of
// GetIpAddrTable because "it's more "official" and less likely to change,
// which means less work for everyone when we upgrade/revise IPHLPAPI," but
// confirms that for Whistler, they are equivalent.
// NTRAID#NTBUG9--2001/04/24-sburns
// sample code:
// //
// // DWORD
// // GetIPv4Addresses(
// // IN LPSOCKET_ADDRESS_LIST *ppList)
// // {
// // LPSOCKET_ADDRESS_LIST pList = NULL;
// // ULONG ulSize = 0;
// // DWORD dwErr;
// // DWORD dwBytesReturned;
// // SOCKET s;
// //
// // *ppList = NULL;
// //
// // s = socket(AF_INET, SOCK_DGRAM, 0);
// // if (s == INVALID_SOCKET)
// // return WSAGetLastError();
// //
// // for (;;) {
// // dwErr = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, pList, ulSize,
// // &dwBytesReturned, NULL, NULL);
// //
// // if (!dwErr) {
// // break;
// // }
// //
// // if (pList) {
// // FREE(pList);
// // pList = NULL;
// // }
// //
// // dwErr = WSAGetLastError();
// // if (dwErr != WSAEFAULT)
// // break;
// //
// // pList = MALLOC(dwBytesReturned);
// // if (!pList) {
// // dwErr = ERROR_NOT_ENOUGH_MEMORY;
// // break;
// // }
// //
// // ulSize = dwBytesReturned;
// // }
// //
// // closesocket(s);
// //
// // *ppList = pList;
// // return dwErr;
// // }
// Returns true if tcp/ip is "working" (can send/receive packets on at least
// one IP address.
bool IsTcpIpFunctioning() { LOG_FUNCTION(IsTcpIpFunctioning);
bool result = false;
// As per nksrin, we will call GetIpAddrTable. If no addresses are in
// the table, then the IP stack is not in a state to send/rcv packets
// with the rest of the world
HRESULT hr = S_OK; BYTE* buf = 0; do { // first, determine the size of the table
ULONG tableSize = 0; DWORD err = ::GetIpAddrTable(0, &tableSize, FALSE); if (err != ERROR_INSUFFICIENT_BUFFER) { LOG(L"GetIpAddrTable for table size failed"); LOG_HRESULT(Win32ToHresult(err)); break; }
// allocate space for the table.
buf = new BYTE[tableSize + 1]; memset(buf, 0, tableSize + 1); PMIB_IPADDRTABLE table = reinterpret_cast<PMIB_IPADDRTABLE>(buf);
LOG(L"Calling GetIpAddrTable");
hr = Win32ToHresult( ::GetIpAddrTable( table, &tableSize, FALSE)); BREAK_ON_FAILED_HRESULT2(hr, L"GetIpAddrTable failed");
LOG(String::format(L"dwNumEntries: %1!d!", table->dwNumEntries));
for (int i = 0; i < table->dwNumEntries; ++i) { DWORD addr = table->table[i].dwAddr; LOG(String::format(L"entry %1!d!", i)); LOG(String::format( L"dwAddr %1!X! (%2!d!.%3!d!.%4!d!.%5!d!)", addr, ((BYTE*)&addr)[0], ((BYTE*)&addr)[1], ((BYTE*)&addr)[2], ((BYTE*)&addr)[3]));
// skip loopback, etc.
if ( INADDR_ANY == addr || INADDR_BROADCAST == addr || INADDR_LOOPBACK == addr || 0x0100007f == addr ) { LOG(L"is loopback/broadcast -- skipping");
continue; }
// Exclude MCAST addresses (class D).
if ( IN_CLASSA(htonl(addr)) || IN_CLASSB(htonl(addr)) || IN_CLASSC(htonl(addr)) ) { LOG(L"is class A/B/C");
result = true; break; }
LOG(L"not class A/B/C -- skipping"); } } while (0);
delete[] buf;
LOG(String::format(L"TCP/IP %1 functioning", result ? L"is" : L"is NOT"));
return result; }
InstallTcpIpPage::InstallTcpIpPage() : DCPromoWizardPage( IDD_INSTALL_TCPIP, IDS_INSTALL_TCPIP_PAGE_TITLE, IDS_INSTALL_TCPIP_PAGE_SUBTITLE) { LOG_CTOR(InstallTcpIpPage); }
InstallTcpIpPage::~InstallTcpIpPage() { LOG_DTOR(InstallTcpIpPage); }
void InstallTcpIpPage::OnInit() { LOG_FUNCTION(InstallTcpIpPage::OnInit); }
bool InstallTcpIpPage::OnSetActive() { LOG_FUNCTION(InstallTcpIpPage::OnSetActive);
State& state = State::GetInstance(); if ( state.RunHiddenUnattended() or (IsTcpIpInstalled() and IsTcpIpFunctioning()) ) { LOG(L"Planning to Skip InstallTcpIpPage");
Wizard& wizard = GetWizard();
if (wizard.IsBacktracking()) { // backup once again
wizard.Backtrack(hwnd); return true; }
int nextPage = Validate(); if (nextPage != -1) { LOG(L"skipping InstallTcpIpPage"); wizard.SetNextPageID(hwnd, nextPage); return true; }
state.ClearHiddenWhileUnattended(); }
Win::PropSheet_SetWizButtons( Win::GetParent(hwnd), PSWIZB_BACK | PSWIZB_NEXT);
return true; }
bool InstallTcpIpPage::OnNotify( HWND /* windowFrom */ , UINT_PTR controlIDFrom, UINT code, LPARAM /* lParam */ ) { // LOG_FUNCTION(InstallTcpIpPage::OnNotify);
bool result = false; if (controlIDFrom == IDC_JUMP) { switch (code) { case NM_CLICK: case NM_RETURN: { ShowTroubleshooter(hwnd, IDS_INSTALL_TCPIP_HELP_TOPIC); result = true; } default: { // do nothing
break; } } } return result; }
int InstallTcpIpPage::Validate() { LOG_FUNCTION(InstallTcpIpPage::Validate);
int nextPage = -1; if (IsTcpIpInstalled() and IsTcpIpFunctioning()) { State& state = State::GetInstance(); switch (state.GetRunContext()) { case State::BDC_UPGRADE: { ASSERT(state.GetOperation() == State::REPLICA); nextPage = IDD_REPLICATE_FROM_MEDIA; // IDD_CONFIG_DNS_CLIENT;
break; } case State::PDC_UPGRADE: { nextPage = IDD_TREE_OR_CHILD; break; } case State::NT5_STANDALONE_SERVER: case State::NT5_MEMBER_SERVER: { nextPage = IDD_REPLICA_OR_DOMAIN; break; } default: { ASSERT(false); break; } } } else { String message = String::load(IDS_INSTALL_TCPIP_FIRST);
popup.Info(hwnd, message); }
return nextPage; }
|