// Copyright (C) 1997 Microsoft Corporation // // paths, part 2 page // // 1-8-97 sburns #include "headers.hxx" #include "page.hpp" #include "Paths2Page.hpp" #include "resource.h" #include "state.hpp" #include "common.hpp" Paths2Page::Paths2Page() : DCPromoWizardPage( IDD_PATHS2, IDS_PATHS2_PAGE_TITLE, IDS_PATHS2_PAGE_SUBTITLE), touchWizButtons(true) { LOG_CTOR(Paths2Page); } Paths2Page::~Paths2Page() { LOG_DTOR(Paths2Page); } String DetermineDefaultSysvolPath() { LOG_FUNCTION(DetermineDefaultSysvolPath); // prefer windir, but if that's not ntfs 5, find one that is. String result = Win::GetSystemWindowsDirectory(); if (FS::GetFileSystemType(result) != FS::NTFS5) { result = GetFirstNtfs5HardDrive(); } else { result += L"\\"; } LOG(result); return result; } void Paths2Page::OnInit() { LOG_FUNCTION(Paths2Page::OnInit); Win::Edit_LimitText(Win::GetDlgItem(hwnd, IDC_SYSVOL), MAX_PATH); State& state = State::GetInstance(); if (state.UsingAnswerFile()) { Win::SetDlgItemText( hwnd, IDC_SYSVOL, Win::ExpandEnvironmentStrings( state.GetAnswerFileOption(State::OPTION_SYSVOL_PATH))); } String root = DetermineDefaultSysvolPath(); if (Win::GetTrimmedDlgItemText(hwnd, IDC_SYSVOL).empty()) { Win::SetDlgItemText( hwnd, IDC_SYSVOL, root + String::load(IDS_SYSVOL_SUFFIX)); } } void Paths2Page::Enable() { // touchWizButtons is managed in the OnCommand handler for EN_KILLFOCUS. // Turns out that if you call PropSheet_SetWizButtons while handling a kill // focus event, you mess up the tab processing so that the focus jumps to // the default wizard button. That's really cool -- NOT! if (touchWizButtons) { int next = !Win::GetTrimmedDlgItemText(hwnd, IDC_SYSVOL).empty() ? PSWIZB_NEXT : 0; Win::PropSheet_SetWizButtons(Win::GetParent(hwnd), PSWIZB_BACK | next); } } bool Paths2Page::OnCommand( HWND /* windowFrom */ , unsigned controlIdFrom, unsigned code) { // LOG_FUNCTION(Paths2Page::OnCommand); bool result = false; switch (controlIdFrom) { case IDC_BROWSE: { if (code == BN_CLICKED) { String path = BrowseForFolder(hwnd, IDS_SYSVOL_BROWSE_TITLE); if (!path.empty()) { Win::SetDlgItemText(hwnd, IDC_SYSVOL, path); } result = true; } break; } case IDC_SYSVOL: { switch (code) { case EN_CHANGE: { SetChanged(controlIdFrom); Enable(); result = true; break; } case EN_KILLFOCUS: { // Since the normalization fully-expands relative paths, the // full pathname may not match what the user entered. So we // update the edit box contents to make sure they realize what // the relative path expands to. // NTRAID#NTBUG9-216148-2000/11/01-sburns String text = Win::GetTrimmedDlgItemText(hwnd, controlIdFrom); if (!text.empty()) { // turn off setting of wizard buttons so that the call to // Enable made by the EN_CHANGE handler (which will be // called when we set the edit box text) will not call // PropSheet_SetWizButtons, which will mess up the tab // processing. touchWizButtons = false; Win::SetDlgItemText( hwnd, controlIdFrom, FS::NormalizePath(text)); touchWizButtons = true; } result = true; break; } default: { // do nothing break; } } break; } default: { // do nothing break; } } return false; } bool Paths2Page::OnSetActive() { LOG_FUNCTION(Paths2Page::OnSetActive); Win::PropSheet_SetWizButtons( Win::GetParent(hwnd), PSWIZB_BACK); State& state = State::GetInstance(); if (state.RunHiddenUnattended()) { int nextPage = Validate(); if (nextPage != -1) { GetWizard().SetNextPageID(hwnd, nextPage); } else { state.ClearHiddenWhileUnattended(); } } Enable(); return true; } // returns true if the path is valid, false if not. Pesters the user on // validation failures. bool ValidateSYSVOLPath(const String& path, HWND parent, unsigned editResID) { LOG_FUNCTION(validateSysvolPath); ASSERT(Win::IsWindow(parent)); ASSERT(!path.empty()); // check that the path is not the same as the database or log paths // previously entered. 313059 State& state = State::GetInstance(); String db = state.GetDatabasePath(); if (db.icompare(path) == 0) { popup.Gripe( parent, editResID, String::format(IDS_SYSVOL_CANT_MATCH_DB, db.c_str())); return false; } String log = state.GetLogPath(); if (log.icompare(path) == 0) { popup.Gripe( parent, editResID, String::format(IDS_SYSVOL_CANT_MATCH_LOG, log.c_str())); return false; } // check that the path is not a parent folder of the database or log // paths previously entered. 320685 if (FS::IsParentFolder(path, db)) { popup.Gripe( parent, editResID, String::format(IDS_SYSVOL_CANT_BE_DB_PARENT, db.c_str())); return false; } if (FS::IsParentFolder(path, log)) { popup.Gripe( parent, editResID, String::format(IDS_SYSVOL_CANT_BE_LOG_PARENT, log.c_str())); return false; } // // if replicating from media, destination sysvol folder may not be any // // of the source paths. // // if (state.ReplicateFromMedia()) // { // String p = state.GetReplicationSourcePath(); // if (p.icompare(path) == 0) // { // popup.Gripe( // parent, // editResID, // String::format(IDS_SYSVOL_CANT_MATCH_SOURCE_PATH, p.c_str())); // return false; // } // } // if you change this, change the error message resource too. static const unsigned SYSVOL_MIN_SPACE_MB = 100; if (!CheckDiskSpace(path, SYSVOL_MIN_SPACE_MB)) { popup.Gripe( parent, editResID, String::format(IDS_SYSVOL_LOW_SPACE, log.c_str())); return false; } return true; } int Paths2Page::Validate() { LOG_FUNCTION(Paths2Page::Validate); int nextPage = -1; String path = FS::NormalizePath(Win::GetTrimmedDlgItemText(hwnd, IDC_SYSVOL)); if ( ValidateDcInstallPath(path, hwnd, IDC_SYSVOL, true) && ValidateSYSVOLPath(path, hwnd, IDC_SYSVOL) ) { State& state = State::GetInstance(); state.SetSYSVOLPath(path); if (state.GetOperation() == State::FOREST) { nextPage = IDD_NEW_SITE; } else { nextPage = IDD_PICK_SITE; } } return nextPage; }