Index: installer/CopyEngine.cpp
===================================================================
--- installer/CopyEngine.cpp	(Revision 25297)
+++ installer/CopyEngine.cpp	(Arbeitskopie)
@@ -74,8 +74,10 @@
 		{
 			status_t err = Start(fWindow->GetSourceMenu(),
 				fWindow->GetTargetMenu());
-			if (err != B_OK)
+			if (err != B_OK) {
 				ERR("Start failed");
+				BMessenger(fWindow).SendMessage(RESET_INSTALL);
+			}
 			break;
 		}
 	}
@@ -182,6 +184,7 @@
 			"Try choosing a different disk or choose to not install optional "
 			"items.", "Try installing anyway", "Cancel", 0,
 			B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
+		BMessenger(fWindow).SendMessage(RESET_INSTALL);
 		return B_OK;
 	}
 
@@ -203,6 +206,7 @@
 	if (strcmp(srcDirectory.Path(), targetDirectory.Path()) == 0) {
 		SetStatusMessage("You can't install the contents of a disk onto "
 			"itself. Please choose a different disk.");
+		BMessenger(fWindow).SendMessage(RESET_INSTALL);
 		return B_OK;
 	}
 
@@ -213,6 +217,7 @@
 			"machine if you proceed.", "OK", "Cancel", 0,
 			B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
 		SetStatusMessage("Installation stopped.");
+		BMessenger(fWindow).SendMessage(RESET_INSTALL);
 		return B_OK;
 	}
 
@@ -230,16 +235,20 @@
 		BDirectory packageDir;
 		int32 count = fPackages->CountItems();
 		for (int32 i = 0; i < count; i++) {
+			if (fControl->CheckUserCanceled())
+				return B_OK;
 			Package *p = static_cast<Package*>(fPackages->ItemAt(i));
 			packageDir.SetTo(&srcDir, p->Folder());
 			CopyFolder(packageDir, targetDir);
 		}
 	}
 
-	LaunchFinishScript(targetDirectory);
+	if (!fControl->CheckUserCanceled()) {
+		LaunchFinishScript(targetDirectory);
 
-	BMessage msg(INSTALL_FINISHED);
-	BMessenger(fWindow).SendMessage(&msg);
+		BMessage msg(INSTALL_FINISHED);
+		BMessenger(fWindow).SendMessage(&msg);
+	}
 
 	return B_OK;
 }
@@ -250,7 +259,8 @@
 {
 	BEntry entry;
 	status_t err;
-	while (srcDir.GetNextEntry(&entry) == B_OK) {
+	while (srcDir.GetNextEntry(&entry) == B_OK
+		&& !fControl->CheckUserCanceled()) {
 		StatStruct statbuf;
 		entry.GetStat(&statbuf);
 		
@@ -299,6 +309,13 @@
 }
 
 
+bool
+CopyEngine::Cancel()
+{
+	return fControl->Cancel();
+}
+
+
 // #pragma mark -
 
 
Index: installer/CopyEngine.h
===================================================================
--- installer/CopyEngine.h	(Revision 25297)
+++ installer/CopyEngine.h	(Arbeitskopie)
@@ -28,6 +28,7 @@
 		void ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu);
 		void SetPackagesList(BList *list);
 		void SetSpaceRequired(off_t bytes) { fSpaceRequired = bytes; };
+		bool Cancel();
 	private:
 		void LaunchInitScript(BPath &path);
 		void LaunchFinishScript(BPath &path);
Index: installer/InstallerCopyLoopControl.cpp
===================================================================
--- installer/InstallerCopyLoopControl.cpp	(Revision 25297)
+++ installer/InstallerCopyLoopControl.cpp	(Arbeitskopie)
@@ -9,7 +9,8 @@
 
 InstallerCopyLoopControl::InstallerCopyLoopControl(InstallerWindow *window)
 	: fWindow(window),
-	fMessenger(window)
+	fMessenger(window),
+	fUserCanceled(false)
 {
 }
 
@@ -48,7 +49,7 @@
 bool
 InstallerCopyLoopControl::CheckUserCanceled()
 {
-	return false;
+	return fUserCanceled;
 }
 
 
@@ -97,3 +98,14 @@
 	return false;
 }
 
+
+bool
+InstallerCopyLoopControl::Cancel()
+{
+	fUserCanceled = (new BAlert("", 
+			"Are you sure you want to to stop the installation?", 
+			"Continue", "Stop", 0,
+			B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0;
+	return fUserCanceled;
+}
+
Index: installer/InstallerWindow.cpp
===================================================================
--- installer/InstallerWindow.cpp	(Revision 25297)
+++ installer/InstallerWindow.cpp	(Arbeitskopie)
@@ -71,6 +71,7 @@
 	: BWindow(frame_rect, "Installer", B_TITLED_WINDOW,
 		B_NOT_ZOOMABLE | B_NOT_RESIZABLE),
 	fDriveSetupLaunched(false),
+	fInstallStatus(kReadyForInstall),
 	fLastSrcItem(NULL),
 	fLastTargetItem(NULL)
 {
@@ -110,6 +111,7 @@
 		"begin_button", "Begin", new BMessage(BEGIN_MESSAGE),
 		B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
 	fBeginButton->MakeDefault(true);
+	fBeginButton->SetEnabled(false);
 	fBackBox->AddChild(fBeginButton);
 
 	fSetupButton = new BButton(BRect(bounds.left + 11, bounds.bottom - 35,
@@ -135,18 +137,18 @@
 	fDestMenu = new BPopUpMenu("scanning" B_UTF8_ELLIPSIS, true, false);
 	fSrcMenu = new BPopUpMenu("scanning" B_UTF8_ELLIPSIS, true, false);
 
-	BRect fieldRect(bounds.left + 50, bounds.top + 70, bounds.right - 13,
+	BRect fieldRect(bounds.left + 13, bounds.top + 70, bounds.right - 13,
 		bounds.top + 90);
 	fSrcMenuField = new BMenuField(fieldRect, "srcMenuField",
 		"Install from: ", fSrcMenu);
-	fSrcMenuField->SetDivider(bounds.right - 274);
+	fSrcMenuField->SetDivider(bounds.right - 300);
 	fSrcMenuField->SetAlignment(B_ALIGN_RIGHT);
 	fBackBox->AddChild(fSrcMenuField);
 
 	fieldRect.OffsetBy(0, 23);
 	fDestMenuField = new BMenuField(fieldRect, "destMenuField",
 		"Onto: ", fDestMenu);
-	fDestMenuField->SetDivider(bounds.right - 274);
+	fDestMenuField->SetDivider(bounds.right - 300);
 	fDestMenuField->SetAlignment(B_ALIGN_RIGHT);
 	fBackBox->AddChild(fDestMenuField);
 
@@ -182,18 +184,40 @@
 InstallerWindow::MessageReceived(BMessage *msg)
 {
 	switch (msg->what) {
+		case RESET_INSTALL:
+			fInstallStatus = kReadyForInstall;
+			fBeginButton->SetEnabled(true);
+			DisableInterface(false);
+			fBeginButton->SetLabel("Begin");
+			break;
 		case START_SCAN:
 			StartScan();
+			fBeginButton->SetEnabled(true);
 			break;
 		case BEGIN_MESSAGE:
 		{
 			BList *list = new BList();
-			int32 size = 0;
-			fPackagesView->GetPackagesToInstall(list, &size);
-			fCopyEngine->SetPackagesList(list);
-			fCopyEngine->SetSpaceRequired(size);
-			BMessenger(fCopyEngine).SendMessage(ENGINE_START);
-			DisableInterface(true);
+			switch (fInstallStatus) {
+				case kReadyForInstall: 
+				{
+					int32 size = 0;
+					fPackagesView->GetPackagesToInstall(list, &size);
+					fCopyEngine->SetPackagesList(list);
+					fCopyEngine->SetSpaceRequired(size);
+					BMessenger(fCopyEngine).SendMessage(ENGINE_START);
+					fBeginButton->SetLabel("Stop");
+					DisableInterface(true);
+					fInstallStatus = kInstalling;
+					break;
+				}
+				case kInstalling:
+					if (fCopyEngine->Cancel())
+						PostMessage(INSTALL_FINISHED);
+					break;
+				case kFinished:
+					QuitRequested();
+					break;
+			}
 			break;
 		}
 		case SHOW_BOTTOM_MESSAGE:
@@ -230,8 +254,11 @@
 				SetStatusMessage(status);
 			} else
 				SetStatusMessage(fLastStatus.String());
+			break;
 		}
 		case INSTALL_FINISHED:
+			fBeginButton->SetLabel("Quit");
+			fInstallStatus = kFinished;
 			DisableInterface(false);
 			break;
 		case B_SOME_APP_LAUNCHED:
@@ -241,6 +268,7 @@
 			if (msg->FindString("be:signature", &signature) == B_OK
 				&& strcasecmp(signature, DRIVESETUP_SIG) == 0) {
 				fDriveSetupLaunched = msg->what == B_SOME_APP_LAUNCHED;
+				fBeginButton->SetEnabled(!fDriveSetupLaunched);
 				DisableInterface(fDriveSetupLaunched);
 				if (fDriveSetupLaunched)
 					SetStatusMessage("Running DriveSetup" B_UTF8_ELLIPSIS
@@ -306,7 +334,6 @@
 void
 InstallerWindow::DisableInterface(bool disable)
 {
-	fBeginButton->SetEnabled(!disable);
 	fSetupButton->SetEnabled(!disable);
 	fSrcMenuField->SetEnabled(!disable);
 	fDestMenuField->SetEnabled(!disable);
Index: installer/InstallerCopyLoopControl.h
===================================================================
--- installer/InstallerCopyLoopControl.h	(Revision 25297)
+++ installer/InstallerCopyLoopControl.h	(Arbeitskopie)
@@ -35,10 +35,12 @@
 		virtual bool ChecksumFile(const entry_ref *);
 		virtual bool SkipAttribute(const char *attributeName);
 		virtual bool PreserveAttribute(const char *attributeName);
+		bool Cancel();
 
 	private:
 		InstallerWindow *fWindow;
 		BMessenger fMessenger;
+		bool fUserCanceled;
 };
 
 #endif
Index: installer/InstallerWindow.h
===================================================================
--- installer/InstallerWindow.h	(Revision 25297)
+++ installer/InstallerWindow.h	(Arbeitskopie)
@@ -20,8 +20,15 @@
 
 #define INSTALLER_RIGHT 402
 
+enum InstallStatus {
+	kReadyForInstall,
+	kInstalling,
+	kFinished
+};
+
 const uint32 STATUS_MESSAGE = 'iSTM';
 const uint32 INSTALL_FINISHED = 'iIFN';
+const uint32 RESET_INSTALL = 'iRSI';
 const char PACKAGES_DIRECTORY[] = "_packages_";
 
 class InstallerWindow : public BWindow {
@@ -46,6 +53,7 @@
 		BButton *fBeginButton, *fSetupButton;
 		DrawButton *fDrawButton;
 		bool fDriveSetupLaunched;
+		InstallStatus fInstallStatus;
 		BTextView *fStatusView;
 		BMenu* fSrcMenu, *fDestMenu;
 		BMenuField* fSrcMenuField, *fDestMenuField;
