mirror of
https://review.haiku-os.org/haiku
synced 2025-01-31 02:35:03 +01:00
cc8605dc75
+alphabranch git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33085 a95241bf-73f2-0310-859d-f6bbb57e9c96
419 lines
9.7 KiB
C++
419 lines
9.7 KiB
C++
/*
|
|
* Copyright 2008, Haiku, Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Michael Pfeiffer <laplace@users.sourceforge.net>
|
|
*/
|
|
|
|
|
|
#include "BootManagerController.h"
|
|
|
|
#include "WizardView.h"
|
|
|
|
#include "EntryPage.h"
|
|
#include "PartitionsPage.h"
|
|
#include "DefaultPartitionPage.h"
|
|
#include "DescriptionPage.h"
|
|
#include "FileSelectionPage.h"
|
|
#include "LegacyBootDrive.h"
|
|
|
|
|
|
#define USE_TEST_BOOT_DRIVE 0
|
|
|
|
#if USE_TEST_BOOT_DRIVE
|
|
#include "TestBootDrive.h"
|
|
#endif
|
|
|
|
|
|
#include <Alert.h>
|
|
#include <Application.h>
|
|
#include <File.h>
|
|
#include <FindDirectory.h>
|
|
#include <Path.h>
|
|
#include <String.h>
|
|
|
|
|
|
BootManagerController::BootManagerController()
|
|
{
|
|
#if USE_TEST_BOOT_DRIVE
|
|
fBootDrive = new TestBootDrive();
|
|
#else
|
|
fBootDrive = new LegacyBootDrive();
|
|
#endif
|
|
|
|
// set defaults
|
|
fSettings.AddBool("install", true);
|
|
fSettings.AddInt32("defaultPartition", 0);
|
|
fSettings.AddInt32("timeout", -1);
|
|
|
|
BPath path;
|
|
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, true) == B_OK) {
|
|
path.Append("bootman/MBR");
|
|
fSettings.AddString("file", path.Path());
|
|
// create directory
|
|
BPath parent;
|
|
if (path.GetParent(&parent) == B_OK) {
|
|
BDirectory directory;
|
|
directory.CreateDirectory(parent.Path(), NULL);
|
|
}
|
|
} else {
|
|
fSettings.AddString("file", "");
|
|
}
|
|
|
|
fReadPartitionsStatus = fBootDrive->ReadPartitions(&fSettings);
|
|
}
|
|
|
|
|
|
BootManagerController::~BootManagerController()
|
|
{
|
|
}
|
|
|
|
|
|
int32
|
|
BootManagerController::InitialState()
|
|
{
|
|
if (fReadPartitionsStatus == B_OK)
|
|
return kStateEntry;
|
|
return kStateErrorEntry;
|
|
}
|
|
|
|
|
|
int32
|
|
BootManagerController::NextState(int32 state)
|
|
{
|
|
switch (state) {
|
|
case kStateEntry:
|
|
{
|
|
bool install;
|
|
fSettings.FindBool("install", &install);
|
|
if (install) {
|
|
if (fBootDrive->IsBootMenuInstalled(&fSettings))
|
|
return kStatePartitions;
|
|
else
|
|
return kStateSaveMBR;
|
|
}
|
|
else
|
|
return kStateUninstall;
|
|
}
|
|
|
|
case kStateErrorEntry:
|
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
break;
|
|
|
|
case kStateSaveMBR:
|
|
if (_SaveMBR())
|
|
return kStateMBRSaved;
|
|
break;
|
|
|
|
case kStateMBRSaved:
|
|
return kStatePartitions;
|
|
|
|
case kStatePartitions:
|
|
if (_HasSelectedPartitions())
|
|
return kStateDefaultPartitions;
|
|
break;
|
|
|
|
case kStateDefaultPartitions:
|
|
return kStateInstallSummary;
|
|
|
|
case kStateInstallSummary:
|
|
if (_WriteBootMenu())
|
|
return kStateInstalled;
|
|
break;
|
|
|
|
case kStateInstalled:
|
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
break;
|
|
|
|
case kStateUninstall:
|
|
if (_RestoreMBR())
|
|
return kStateUninstalled;
|
|
break;
|
|
|
|
case kStateUninstalled:
|
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
break;
|
|
}
|
|
// cannot leave the current state/page
|
|
return -1;
|
|
}
|
|
|
|
|
|
bool
|
|
BootManagerController::_HasSelectedPartitions()
|
|
{
|
|
BMessage message;
|
|
for (int32 i = 0; fSettings.FindMessage("partition", i, &message) == B_OK; i ++) {
|
|
bool show;
|
|
if (message.FindBool("show", &show) == B_OK && show)
|
|
return true;
|
|
}
|
|
|
|
BAlert* alert = new BAlert("info", "At least one partition must be selected!",
|
|
"OK");
|
|
alert->Go();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool
|
|
BootManagerController::_WriteBootMenu()
|
|
{
|
|
BAlert* alert = new BAlert("confirm", "About to write the boot menu "
|
|
"to disk. Are you sure you want to continue?", "Write Boot Menu", "Back",
|
|
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
|
|
|
if (alert->Go() == 1)
|
|
return false;
|
|
|
|
fWriteBootMenuStatus = fBootDrive->WriteBootMenu(&fSettings);
|
|
return true;
|
|
}
|
|
|
|
|
|
bool
|
|
BootManagerController::_SaveMBR()
|
|
{
|
|
BString path;
|
|
fSettings.FindString("file", &path);
|
|
BFile file(path.String(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
|
|
fSaveMBRStatus = fBootDrive->SaveMasterBootRecord(&fSettings, &file);
|
|
return true;
|
|
}
|
|
|
|
|
|
bool
|
|
BootManagerController::_RestoreMBR()
|
|
{
|
|
BString disk;
|
|
BString path;
|
|
fSettings.FindString("disk", &disk);
|
|
fSettings.FindString("file", &path);
|
|
|
|
BString message;
|
|
message << "About to restore the Master Boot Record (MBR) of "
|
|
<< disk << " from " << path << ". "
|
|
"Do you wish to continue?";
|
|
BAlert* alert = new BAlert("confirm", message.String(),
|
|
"Restore MBR", "Back",
|
|
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
|
if (alert->Go() == 1)
|
|
return false;
|
|
|
|
BFile file(path.String(), B_READ_ONLY);
|
|
fRestoreMBRStatus = fBootDrive->RestoreMasterBootRecord(&fSettings, &file);
|
|
return true;
|
|
}
|
|
|
|
|
|
WizardPageView*
|
|
BootManagerController::CreatePage(int32 state, WizardView* wizard)
|
|
{
|
|
WizardPageView* page = NULL;
|
|
BRect frame = wizard->PageFrame();
|
|
|
|
switch (state) {
|
|
case kStateEntry:
|
|
page = new EntryPage(&fSettings, frame, "entry");
|
|
wizard->SetPreviousButtonHidden(true);
|
|
break;
|
|
case kStateErrorEntry:
|
|
page = _CreateErrorEntryPage(frame);
|
|
wizard->SetPreviousButtonHidden(true);
|
|
wizard->SetNextButtonLabel("Done");
|
|
break;
|
|
case kStateSaveMBR:
|
|
page = _CreateSaveMBRPage(frame);
|
|
wizard->SetPreviousButtonHidden(false);
|
|
break;
|
|
case kStateMBRSaved:
|
|
page = _CreateMBRSavedPage(frame);
|
|
break;
|
|
case kStatePartitions:
|
|
page = new PartitionsPage(&fSettings, frame, "partitions");
|
|
wizard->SetPreviousButtonHidden(false);
|
|
break;
|
|
case kStateDefaultPartitions:
|
|
page = new DefaultPartitionPage(&fSettings, frame, "default");
|
|
break;
|
|
case kStateInstallSummary:
|
|
page = _CreateInstallSummaryPage(frame);
|
|
wizard->SetNextButtonLabel("Next");
|
|
break;
|
|
case kStateInstalled:
|
|
page = _CreateInstalledPage(frame);
|
|
wizard->SetNextButtonLabel("Done");
|
|
break;
|
|
case kStateUninstall:
|
|
page = _CreateUninstallPage(frame);
|
|
wizard->SetPreviousButtonHidden(false);
|
|
wizard->SetNextButtonLabel("Next");
|
|
break;
|
|
case kStateUninstalled:
|
|
// TODO prevent overwriting MBR after clicking "Previous"
|
|
page = _CreateUninstalledPage(frame);
|
|
wizard->SetNextButtonLabel("Done");
|
|
break;
|
|
}
|
|
|
|
return page;
|
|
}
|
|
|
|
|
|
WizardPageView*
|
|
BootManagerController::_CreateErrorEntryPage(BRect frame)
|
|
{
|
|
BString description;
|
|
|
|
if (fReadPartitionsStatus == kErrorBootSectorTooSmall)
|
|
description <<
|
|
"Partition Table Not Compatible\n\n"
|
|
"The partition table of the first hard disk is not compatible "
|
|
"with Boot Manager.\n"
|
|
"Boot Manager needs 2 KB available space before the first partition.";
|
|
else
|
|
description <<
|
|
"Error Reading Partition Table\n\n"
|
|
"Boot Manager is unable to read the partition table!";
|
|
|
|
return new DescriptionPage(frame, "errorEntry", description.String(), true);
|
|
}
|
|
|
|
|
|
WizardPageView*
|
|
BootManagerController::_CreateSaveMBRPage(BRect frame)
|
|
{
|
|
BString description;
|
|
BString disk;
|
|
fSettings.FindString("disk", &disk);
|
|
|
|
description <<
|
|
"Backup Master Boot Record\n\n"
|
|
"The Master Boot Record (MBR) of the boot device:\n"
|
|
"\t" << disk << "\n"
|
|
"will now be saved to disk. Please select a file to "
|
|
"save the MBR into.\n\n"
|
|
"If something goes wrong with the installation or if "
|
|
"you later wish to remove the boot menu, simply run the "
|
|
"bootman program and choose the 'Uninstall' option.";
|
|
|
|
return new FileSelectionPage(&fSettings, frame, "saveMBR", description.String(),
|
|
B_SAVE_PANEL);
|
|
}
|
|
|
|
|
|
WizardPageView*
|
|
BootManagerController::_CreateMBRSavedPage(BRect frame)
|
|
{
|
|
BString description;
|
|
BString file;
|
|
fSettings.FindString("file", &file);
|
|
|
|
if (fSaveMBRStatus == B_OK) {
|
|
description <<
|
|
"Old Master Boot Record Saved\n\n"
|
|
"The old Master Boot Record was successfully save to "
|
|
<< file << ".\n";
|
|
} else {
|
|
description <<
|
|
"Old Master Boot Record Saved Failure\n\n"
|
|
"The old Master Boot Record could not be saved to "
|
|
<< file << ".\n";
|
|
}
|
|
|
|
return new DescriptionPage(frame, "summary", description.String(), true);
|
|
}
|
|
|
|
|
|
WizardPageView*
|
|
BootManagerController::_CreateInstallSummaryPage(BRect frame)
|
|
{
|
|
BString description;
|
|
BString disk;
|
|
fSettings.FindString("disk", &disk);
|
|
|
|
description <<
|
|
"Summary\n\n"
|
|
"About to write the following boot menu to the boot disk "
|
|
"(" << disk << "). Please verify the information below "
|
|
"before continuing.\n\n";
|
|
|
|
BMessage message;
|
|
for (int32 i = 0; fSettings.FindMessage("partition", i, &message) == B_OK; i ++) {
|
|
|
|
bool show;
|
|
if (message.FindBool("show", &show) != B_OK || !show)
|
|
continue;
|
|
|
|
BString name;
|
|
BString path;
|
|
message.FindString("name", &name);
|
|
message.FindString("path", &path);
|
|
description << name << "\t(" << path << ")\n";
|
|
}
|
|
|
|
return new DescriptionPage(frame, "summary", description.String(), true);
|
|
}
|
|
|
|
|
|
WizardPageView*
|
|
BootManagerController::_CreateInstalledPage(BRect frame)
|
|
{
|
|
const char* description;
|
|
|
|
if (fWriteBootMenuStatus == B_OK) {
|
|
description = "Installation Boot Menu Completed\n\n"
|
|
"The boot manager has been successfully installed "
|
|
"on your system.";
|
|
} else {
|
|
description = "Installation Boot Menu Failed\n\n"
|
|
"An error occured writing the boot menu. The Master Boot Record "
|
|
"might be destroyed, you should restore the MBR now!";
|
|
}
|
|
|
|
return new DescriptionPage(frame, "done", description, true);
|
|
}
|
|
|
|
|
|
WizardPageView*
|
|
BootManagerController::_CreateUninstallPage(BRect frame)
|
|
{
|
|
BString description;
|
|
|
|
description <<
|
|
"Uninstall Boot Manager\n\n"
|
|
"Please locate the Master Boot Record (MBR) save file to "
|
|
"restore from. This is the file that was created when the "
|
|
"boot manager was first installed.";
|
|
|
|
return new FileSelectionPage(&fSettings, frame, "restoreMBR", description.String(),
|
|
B_OPEN_PANEL);
|
|
}
|
|
|
|
|
|
WizardPageView*
|
|
BootManagerController::_CreateUninstalledPage(BRect frame)
|
|
{
|
|
BString description;
|
|
BString disk;
|
|
BString file;
|
|
fSettings.FindString("disk", &disk);
|
|
fSettings.FindString("file", &file);
|
|
|
|
if (fRestoreMBRStatus == B_OK) {
|
|
description <<
|
|
"Uninstallation Boot Menu Completed\n\n"
|
|
"The Master Boot Record of the boot device "
|
|
"(" << disk << ") has been successfully restored from "
|
|
<< file << ".";
|
|
} else {
|
|
description <<
|
|
"Uninstallation Boot Menu Failed\n\n"
|
|
"The Master Boot Record could not be restored!";
|
|
}
|
|
|
|
return new DescriptionPage(frame, "summary", description.String(), true);
|
|
}
|