⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setup.cpp

📁 虚幻的再开发程序包源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*=============================================================================
	Filer.cpp: Unreal installer/filer.
	Copyright 1997-1999 Epic Games, Inc. All Rights Reserved.

Revision history:
	* Created by Tim Sweeney.
=============================================================================*/

// System includes.
#pragma warning( disable : 4201 )
#define STRICT
#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
#include <io.h>
#include <direct.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include "Res\resource.h"

// Unreal includes.
#include "SetupPrivate.h"
#include "USetupDefinitionWindows.h"
#include "Window.h"

/*-----------------------------------------------------------------------------
	Globals.
-----------------------------------------------------------------------------*/

// Package implementation.
IMPLEMENT_PACKAGE(Setup)

// Functions.
class WWizardPage* NewAutoPlayPage( class WFilerWizard* InOwner, UBOOL ShowInstallOptions );
class FInstallPoll GNoPoll;

// Memory allocator.
#include <malloc.h>
#include "FMallocAnsi.h"
FMallocAnsi Malloc;

// Error handler.
#include "FOutputDeviceWindowsError.h"
FOutputDeviceWindowsError Error;

// Feedback.
#include "FFeedbackContextWindows.h"
FFeedbackContextWindows Warn;

// File manager.
#include "FFileManagerWindows.h"
FFileManagerWindows FileManager;

// Config.
#include "FConfigCacheIni.h"

/*-----------------------------------------------------------------------------
	Helpers.
-----------------------------------------------------------------------------*/

// HRESULT checking.
#define verifyHRESULT(fn) {HRESULT hRes=fn; if( hRes!=S_OK ) appErrorf( TEXT(#fn) TEXT(" failed (%08X)"), hRes );}
#define verifyHRESULTSlow(fn) if(fn){}

void regSet( HKEY Base, FString Dir, FString Key, FString Value )
{
	guard(regSet);
	HKEY hKey = NULL;
	check(RegCreateKeyX( Base, *Dir, &hKey )==ERROR_SUCCESS);
	check(RegSetValueExX( hKey, *Key, 0, REG_SZ, (BYTE*)*Value, (Value.Len()+1)*sizeof(TCHAR) )==ERROR_SUCCESS);
	check(RegCloseKey( hKey )==ERROR_SUCCESS);
	unguard;
}
UBOOL regGet( HKEY Base, FString Dir, FString Key, FString& Str )
{
	guard(regGetFString);
	HKEY hKey = NULL;
	if( RegOpenKeyX( Base, *Dir, &hKey )==ERROR_SUCCESS )
	{
		TCHAR Buffer[4096]=TEXT("");
		DWORD Type=REG_SZ, BufferSize=sizeof(Buffer);
		if
		(	RegQueryValueExX( hKey, *Key, 0, &Type, (BYTE*)Buffer, &BufferSize )==ERROR_SUCCESS
		&&	Type==REG_SZ )
		{
			Str = Buffer;
			return 1;
		}
	}
	Str = TEXT("");
	return 0;
	unguard;
}
SQWORD FreeSpace( const TCHAR* Folder )
{
	guard(FreeSpace);
	if( appStrlen(Folder) && appIsAlpha(Folder[0]) )
	{
		TCHAR Root[]=TEXT("C:") PATH_SEPARATOR;
		Root[0] = Folder[0];
		DWORD SectorsPerCluster=0, BytesPerSector=0, FreeClusters=0, TotalClusters=0;
		GetDiskFreeSpaceX( Root, &SectorsPerCluster, &BytesPerSector, &FreeClusters, &TotalClusters );
		return (QWORD)BytesPerSector * (QWORD)SectorsPerCluster * (QWORD)FreeClusters;
	}
	else return 0;
	unguard;
}

//
// Remove a directory if it's empty. Returns error.
//
static UBOOL IsDrive( const TCHAR* Path )
{
	if( appStricmp(Path,TEXT(""))==0 )
		return 1;
	else if( appToUpper(Path[0])!=appToLower(Path[0]) && Path[1]==':' && Path[2]==0 )
		return 1;
	else if( appStricmp(Path,TEXT("\\"))==0 )
		return 1;
	else if( appStricmp(Path,TEXT("\\\\"))==0 )
		return 1;
	else if( Path[0]=='\\' && Path[1]=='\\' && !appStrchr(Path+2,'\\') )
		return 1;
	else if( Path[0]=='\\' && Path[1]=='\\' && appStrchr(Path+2,'\\') && !appStrchr(appStrchr(Path+2,'\\')+1,'\\') )
		return 1;
	else
		return 0;
}
UBOOL RemoveEmptyDirectory( FString Dir )
{
	for( ; ; )
	{
		if( Dir.Right(1)==PATH_SEPARATOR )
			Dir = Dir.LeftChop(1);
		if( IsDrive(*Dir) )
			break;
		TArray<FString> List = GFileManager->FindFiles( *(Dir * TEXT("*")), 1, 1 );
		if( List.Num() )
			break;
		if( !GFileManager->DeleteDirectory( *Dir, 1, 0 ) )
			return 0;
		while( Dir.Len() && Dir.Right(1)!=PATH_SEPARATOR )
			Dir = Dir.LeftChop(1);
	}
	return 1;
}
void LocalizedFileError( const TCHAR* Key, const TCHAR* AdviceKey, const TCHAR* Filename )
{
	guard(LocalizedError);
	const TCHAR* Str = appGetSystemErrorMessage();
	FString Msg = FString::Printf( TEXT("%s: %s (%s)\n\n%s"), LocalizeError(Key), Filename, Str, LocalizeError(AdviceKey)  );
	appErrorf( *Msg );
	unguard;
}

/*-----------------------------------------------------------------------------
	Install wizard.
-----------------------------------------------------------------------------*/

// Filer wizard.
class WFilerWizard : public WWizardDialog
{
	DECLARE_WINDOWCLASS(WFilerWizard,WWizardDialog,Setup)

	// Config info.
	WLabel LogoStatic;
	FWindowsBitmap LogoBitmap;
	USetupDefinitionWindows* Manager;

	// Constructor.
	WFilerWizard()
	:	LogoStatic		( this, IDC_Logo )
	,   Manager         ( new(UObject::CreatePackage(NULL,MANIFEST_FILE), TEXT("Setup"))USetupDefinitionWindows )
	{
		guard(WFilerWizard::WFilerWizard);
		Manager->Init();
		if( Manager->Uninstalling )
			Manager->CreateRootGroup();
		unguard;
	}

	// WWindow interface.
	void OnInitDialog()
	{
		guard(WFilerWizard::OnInitDialog);

		// Dialog init.
		WWizardDialog::OnInitDialog();
		Manager->hWndManager = hWnd;
		SendMessageX( *this, WM_SETICON, ICON_BIG, (WPARAM)LoadIconIdX(hInstance,IDICON_Setup1) );
		if( Manager->Logo==TEXT("") || !Manager->LocateSourceFile( Manager->Logo ) )
		{
			Manager->Logo = TEXT("..\\Help\\Logo.bmp");//!!for setup
			if( GFileManager->FileSize(*Manager->Logo)<=0 )
				Manager->Logo = TEXT("Logo.bmp");//!!for uninstaller
		}
		LogoBitmap.LoadFile( *Manager->Logo );
		SendMessageX( LogoStatic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)LogoBitmap.GetBitmapHandle() );

		// Windows init.
		verifyHRESULT(CoInitialize(NULL));

		unguard;
	}

	// WFilerWizard interface.
	void OnFinish()
	{
		guard(WFilerWizard::OnFinish);
		WWizardDialog::OnFinish();
		Manager->PreExit();
		unguard;
	}
};

/*-----------------------------------------------------------------------------
	Product information.
-----------------------------------------------------------------------------*/

// Product information box.
class WProductInfo : public WDialog
{
	DECLARE_WINDOWCLASS(WProductInfo,WDialog,Setup)

	// Variables.
	USetupProduct* SetupProduct;
	WLabel ProductText;
	WLabel VersionText;
	WLabel DeveloperText;
	WButton ProductHolder;
	WUrlButton Product;
	WUrlButton Version;
	WUrlButton Developer;

	// Constructor.
	WProductInfo( WWindow* InOwner, USetupDefinition* Manager, USetupProduct* InSetupProduct )
	: WDialog		( TEXT("ProductInfo"), IDDIALOG_ProductInfo, InOwner )
	, SetupProduct  ( InSetupProduct )
	, ProductText   ( this, IDC_ProductText )
	, VersionText   ( this, IDC_VersionText )
	, DeveloperText ( this, IDC_DeveloperText )
	, ProductHolder ( this, IDC_ProductHolder )
	, Product       ( this, TEXT(""), IDC_Product   )
	, Version       ( this, TEXT(""), IDC_Version   )
	, Developer     ( this, TEXT(""), IDC_Developer )
	{}

	// WDialog interface.
	void LanguageChange()
	{
		guard(WProductInfo::LanguageChange);
		//!!super::languagechange

		// Product text.
		Product  .URL    =  SetupProduct->ProductURL;
		Version  .URL    =  SetupProduct->VersionURL;
		Developer.URL    =  SetupProduct->DeveloperURL;
		Product  .SetText( *SetupProduct->LocalProduct );
		Developer.SetText( *SetupProduct->Developer    );
		Version  .SetText( *SetupProduct->Version      );

		// General text.
		ProductText   .SetText(Localize("IDDIALOG_ProductInfo","IDC_ProductText"));
		VersionText   .SetText(Localize("IDDIALOG_ProductInfo","IDC_VersionText"));
		DeveloperText .SetText(Localize("IDDIALOG_ProductInfo","IDC_DeveloperText"));
		ProductHolder .SetText(Localize("IDDIALOG_ProductInfo","IDC_ProductHolder"));

		unguard;
	}
};

/*-----------------------------------------------------------------------------
	Failed requirement.
-----------------------------------------------------------------------------*/

// A password dialog box.
class WFailedRequirement : public WDialog
{
	DECLARE_WINDOWCLASS(WFailedRequirement,WDialog,Setup)

	// Controls.
	WCoolButton OkButton;
	WProductInfo ProductInfo;
	WLabel FailedText;
	FString Title;
	FString Message;

	// Constructor.
	WFailedRequirement( WWindow* InOwnerWindow, USetupDefinition* Manager, USetupProduct* InProduct, const TCHAR* InTitle, const TCHAR* InMessage )
	: WDialog	  ( TEXT("FailedRequirement"), IDDIALOG_FailedRequirement, InOwnerWindow )
	, FailedText  ( this, IDC_FailedMessage )
	, OkButton    ( this, IDOK, FDelegate(this,(TDelegate)EndDialogTrue) )
	, ProductInfo ( this, Manager, InProduct )
	, Title       ( InTitle )
	, Message     ( InMessage )
	{}
	void OnInitDialog()
	{
		guard(WFailedRequirement::OnInitDialog);
		WDialog::OnInitDialog();
		SetText( *Title );
		ProductInfo.OpenChildWindow( IDC_ProductInfoHolder, 1 );
		ProductInfo.LanguageChange();
		ProductInfo.ProductHolder.SetText( Localize("IDDIALOG_FailedRequirement","IDC_ProductHolder") );
		FailedText.SetText( LineFormat(*Message) );
		unguard;
	}
};

/*-----------------------------------------------------------------------------
	Install components.
-----------------------------------------------------------------------------*/

// Base of components page.
class WFilerPageComponentsBase : public WWizardPage
{
	DECLARE_WINDOWCLASS(WFilerPageComponentsBase,WWizardPage,Setup)
	WFilerWizard* Owner;
	WFilerPageComponentsBase( const TCHAR* InText, INT InID, WFilerWizard* InOwner )
	: WWizardPage( InText, InID, InOwner )
	, Owner( InOwner )
	{}
	virtual void OnGroupChange( class FComponentItem* Group )=0;
};

// An component list item.
class FComponentItem : public FHeaderItem
{
public:
	// Variables.
	WFilerPageComponentsBase* OwnerComponents;
	USetupGroup* SetupGroup;
	UBOOL Forced;

	// Constructors.
	FComponentItem( WFilerPageComponentsBase* InOwnerComponents, USetupGroup* InSetupGroup, WPropertiesBase* InOwnerProperties, FTreeItem* InParent )
	: FHeaderItem		( InOwnerProperties, InParent, 1 )
	, OwnerComponents	( InOwnerComponents )
	, SetupGroup        ( InSetupGroup )
	, Forced            ( 0 )
	{
		guard(FComponentItem::FComponentItem);

		// Get subgroups.
		Sorted = SetupGroup->Manager->Uninstalling;
		for( TArray<USetupGroup*>::TIterator It(SetupGroup->Subgroups); It; ++It )
			if( (*It)->Visible )
				Children.AddItem( new(TEXT("FComponentItem"))FComponentItem(OwnerComponents,*It,OwnerProperties,this) );
		Expandable = Children.Num()>0;

		unguard;
	}
	FRect GetCheckboxRect()
	{
		guard(FComponentItem::GetCheckboxRect);
		return FRect(GetRect()-GetRect().Min).Right(16).Inner(FPoint(0,1))+FPoint(0,1);
		unguard;
	}

	// FTreeItem interface.
	UBOOL Greyed()
	{
		guard(FComponentItem::Greyed);
		if( SetupGroup->Manager->Uninstalling )
			return Forced;
		else
			for( FComponentItem* Item=(FComponentItem*)Parent; Item; Item=(FComponentItem*)Item->Parent )
				if( !Item->SetupGroup->Selected )
					return 1;
		return 0;
		unguard;
	}
	void Draw( HDC hDC )
	{
		guard(FComponentItem::Draw);
		FHeaderItem::Draw( hDC );
		DWORD GreyedFlags = SetupGroup->Manager->Uninstalling ? (DFCS_INACTIVE|DFCS_CHECKED) : (DFCS_INACTIVE);
		DrawFrameControl( hDC, GetCheckboxRect()+GetRect().Min, DFC_BUTTON, DFCS_BUTTONCHECK|(Greyed()?GreyedFlags:0)|(SetupGroup->Selected?DFCS_CHECKED:0) );
		unguard;
	}
	void ToggleSelection()
	{
		guard(FTreeItem::ToggleSelection);
		if( SetupGroup->Optional && !Greyed() )
		{
			SetupGroup->Selected = !SetupGroup->Selected;
			OwnerComponents->OnGroupChange( this );
			InvalidateRect( OwnerProperties->List, NULL, 0 );
			UpdateWindow( OwnerProperties->List );
		}
		unguard;
	}
	void OnItemDoubleClick()
	{
		guard(FTreeItem::OnItemDoubleClick);
		ToggleSelection();
		unguard;
	}
	void OnItemLeftMouseDown( FPoint P )
	{
		guard(FComponentItem::OnItemLeftMouseDown);
		if( GetCheckboxRect().Inner(FPoint(-1,-1)).Contains(P) )
			ToggleSelection();
		else
			FHeaderItem::OnItemLeftMouseDown( P );
		unguard;
	}
	void OnItemSetFocus()
	{
		guard(FComponentItem::OnItemSetFocus);
		FHeaderItem::OnItemSetFocus();
		OwnerComponents->OnGroupChange( this );
		unguard;
	}
	QWORD GetId() const
	{
		guard(FConfigItem::GetId);
		return (INT)this;
		unguard;
	}
	virtual FString GetCaption() const
	{
		guard(FConfigItem::GetText);
		return SetupGroup->Caption;
		unguard;
	}
};

// Group properties.
class WComponentProperties : public WProperties
{
	DECLARE_WINDOWCLASS(WComponentProperties,WProperties,Setup)
	FComponentItem Root;
	WComponentProperties( WFilerPageComponentsBase* InComponents )
	: WProperties( NAME_None, InComponents )
	, Root( InComponents, InComponents->Owner->Manager->RootGroup, this, NULL )
	{
		ShowTreeLines = 0;
	}
	FTreeItem* GetRoot()
	{
		return &Root;
	}
};

/*-----------------------------------------------------------------------------
	Install wizard pages.
-----------------------------------------------------------------------------*/

// Progess.
class WFilerPageProgress : public WWizardPage, public FInstallPoll
{
	DECLARE_WINDOWCLASS(WFilerPageProgress,WWizardPage,Setup)

	// Variables.
	WFilerWizard* Owner;
	USetupDefinition* Manager;
	WLabel InstallText;
	WLabel InstallingText;
	WLabel ProgressText;
	WLabel TotalText;
	WLabel Installing;
	WProgressBar Progress;
	WProgressBar Total;
	UBOOL Finished;
	UBOOL CancelFlag;

	// Constructor.
	WFilerPageProgress( WFilerWizard* InOwner, const TCHAR* Template )
	: WWizardPage   ( Template, IDDIALOG_FilerPageProgress, InOwner )
	, Owner         ( InOwner )
	, Manager       ( InOwner->Manager )
	, InstallText   ( this, IDC_InstallText )
	, InstallingText( this, IDC_InstallingText )
	, ProgressText  ( this, IDC_ProgressText )
	, TotalText     ( this, IDC_TotalText )
	, Installing    ( this, IDC_Installing )
	, Progress      ( this, IDC_Progress )
	, Total         ( this, IDC_Total )
	, Finished      ( 0 )
	, CancelFlag	( 0 )
	{}

	// FInstallPoll interface.
	UBOOL Poll( const TCHAR* Label, SQWORD LocalBytes, SQWORD LocalTotal, SQWORD RunningBytes, SQWORD TotalBytes )
	{
		guard(WWizardPageProgress::Poll);
		static TCHAR Saved[256]=TEXT("");
		if( appStricmp(Label,Saved)!=0 )
		{
			Installing.SetText( Label );
			appStrcpy( Saved, Label );
		}
		Progress.SetProgress( LocalBytes, LocalTotal );
		Total.SetProgress( RunningBytes, TotalBytes );
		MSG Msg;
		while( PeekMessageX(&Msg,NULL,0,0,1) )
			DispatchMessageX(&Msg);
		UpdateWindow( *this );
		if( CancelFlag )
			if( MessageBox( *OwnerWindow, *FString::Printf(LocalizeGeneral(TEXT("CancelPrompt")),*Manager->LocalProduct), LocalizeGeneral(TEXT("InstallCancel")), MB_YESNO )==IDYES )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -