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

📄 usetupdefinition.cpp

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

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

#include "SetupPrivate.h"

/*-----------------------------------------------------------------------------
	Helper functions.
-----------------------------------------------------------------------------*/

// Text formatting.
inline const TCHAR* LineFormat( const TCHAR* In )
{
	guard(LineFormat);
	static TCHAR Result[4069];
	TCHAR* Ptr = Result;
	while( *In )
		*Ptr++ = *In++!='\\' ? In[-1] : *In++=='n' ? '\n' : In[-1];
	*Ptr++ = 0;
	return Result;
	unguard;
}

/*-----------------------------------------------------------------------------
	USetupObject.
-----------------------------------------------------------------------------*/

IMPLEMENT_CLASS(USetupObject);

/*-----------------------------------------------------------------------------
	USetupProduct.
-----------------------------------------------------------------------------*/

IMPLEMENT_CLASS(USetupProduct);

/*-----------------------------------------------------------------------------
	USetupGroup.
-----------------------------------------------------------------------------*/

USetupGroup::USetupGroup()
: File(E_NoInit), Copy(E_NoInit), Group(E_NoInit), Folder(E_NoInit), Backup(E_NoInit), Delete(E_NoInit), Ini(E_NoInit), Requires(E_NoInit)
{
	guard(USetupGroup::USetupGroup);
	check(Manager);
	if( Manager->Uninstalling )
	{
		Optional = 1;
		Visible  = 1;
		Selected = 0;
	}
	for( TArray<FString>::TIterator It(Group); It; ++It )
	{
		Subgroups.AddItem( ConstructObject<USetupGroup>(GetClass(),GetOuter(),**It) );
	}
	unguard;
}
SQWORD USetupGroup::SpaceRequired()
{
	guard(USetupGroup::SpaceRequired);
	SQWORD Count=0;
	if( Selected )
	{
		for( TArray<USetupGroup*>::TIterator ItG(Subgroups); ItG; ++ItG )
		{
			Count += (*ItG)->SpaceRequired();
		}
		for( TArray<FString>::TIterator ItF(File); ItF; ++ItF )
		{
			FFileInfo Info(*ItF);
			if( Info.Lang==TEXT("") || Info.Lang==UObject::GetLanguage() )
				Count += Info.Size + PER_FILE_OVERHEAD;
		}
	}
	return Count;
	unguard;
}
USetupDefinition* USetupGroup::Manager;
IMPLEMENT_CLASS(USetupGroup);

/*-----------------------------------------------------------------------------
	USetupDefinition.
-----------------------------------------------------------------------------*/

USetupDefinition::USetupDefinition()
:	ConfigFile		( MANIFEST_FILE )
, 	Requires        ( E_NoInit )
{}
void USetupDefinition::Init()
{
	guard(USetupDefinition::Init);

	// Figure out source folder.
	SrcPath = appBaseDir();
	if( SrcPath.Right(1)==PATH_SEPARATOR )
		SrcPath = SrcPath.LeftChop( 1 );
	while( SrcPath.Len() && SrcPath.Right(1)!=PATH_SEPARATOR )
		SrcPath = SrcPath.LeftChop( 1 );
	if( SrcPath.Len() )
		SrcPath = SrcPath.LeftChop( 1 );

	// See if installing a packed .umod file.
	FString Token;
	const TCHAR* Cmd = appCmdLine();
	ParseToken( Cmd, Token, 0 );
	if( Token==TEXT("install") || (Token==TEXT("") && MasterProduct==TEXT("")) )
	{
		// Installing.
		if( Token==TEXT("install") )
		{
			// Verify that the specified module exists.
			ParseToken( Cmd, Token, 0 );
			INT RealSize = GFileManager->FileSize(*Token);
			if( RealSize<=0 )
				appErrorf( TEXT("Can't find module %s"), *Token );

			// Read the module's header.
			FArchive* Ar = GFileManager->CreateFileReader(*Token);
			check(Ar);
			FArchiveHeader* Arc = new FArchiveHeader;
			INT HeaderPos = Ar->TotalSize()-ARCHIVE_HEADER_SIZE;
			Ar->Seek( HeaderPos );
			*Ar << *Arc;

			// Verify the module's correctness.
			if( Ar->IsError() || Arc->Magic!=MOD_MAGIC || Arc->Ver!=ARCHIVE_VERSION || Arc->FileSize!=RealSize )
				appErrorf( TEXT("The module %s is incomplete -- probably due to an incomplete or failed download"), *Token );

			// Verify the module's CRC, unless we're an executable (in which case the sfx already did that).
			if( Token.Right(4)!=TEXT(".exe") )
			{
				Ar->Seek( 0 );
				INT CRC=0;
				BYTE Buffer[16384];
				for( INT i=0; i<HeaderPos; i+=sizeof(Buffer) )
				{
					INT Count = Min<INT>( HeaderPos-i, sizeof(Buffer) );
					Ar->Serialize( Buffer, Count );
					if( Ar->IsError() )
						appErrorf( TEXT("The module %s can't be read"), *Token );
					CRC = appMemCrc( Buffer, Count, CRC );
				}
				if( CRC!=Arc->CRC )
					appErrorf( TEXT("The module %s is corrupt -- probably due to an incomplete or corrupt download"), *Token );
			}

			// Read the module's directory.
			Ar->Seek( Arc->TableOffset );
			*Ar << Arc->Items;
			check(!Ar->IsError());
			GFileManager = CreateFileManagerArc( GFileManager, *Token, Arc );
			Token = TEXT("");
			ParseToken( Cmd, Token, 0 );

			// Reload config from the new filer manager.
			GConfig->Flush(1,MANIFEST_FILE MANIFEST_EXT);
			LoadConfig();
			LoadLocalized();
		}

		// Detach configuration file so we can modify it locally.
		GConfig->Detach( *ConfigFile );
		Manifest = 1;
	}
	else if( Token==TEXT("reallyuninstall") )
	{
		// Running uninstaller from temp folder.
		ParseToken( Cmd, Product, 0 );
		Parse( appCmdLine(), TEXT("PATH="), DestPath );
		if( DestPath.Right(1)==PATH_SEPARATOR )
			DestPath = DestPath.LeftChop( 1 );
		while( DestPath.Len() && DestPath.Right(1)!=PATH_SEPARATOR )
			DestPath = DestPath.LeftChop( 1 );
		Uninstalling = 1;
	}
	else if( Token==TEXT("uninstall") || (Token==TEXT("") && MasterProduct!=TEXT("")) )
	{
		// Running uninstaller for the first time.
		NoRun = 1;
		if( Token==TEXT("uninstall") )
			ParseToken( Cmd, Product, 0 );
		else
			Product = MasterProduct;
		PerformUninstallCopy();
	}
	else appErrorf(TEXT("Setup: Unknown disposition"));

	// Validate everything.
	if( !appAtoi(*Version) && !Uninstalling && !NoRun )
		appErrorf( TEXT("Setup: Missing version number") );

	// Determine whether known to be installed.
	Exists
	=	GetRegisteredProductFolder( Product, RegistryFolder )
	&&	GFileManager->FileSize(*(RegistryFolder*TEXT("System")*SETUP_INI))>0;

	// If this is a mod, find required product's path.
	FolderExists = Exists;
	if( !Exists && !Uninstalling && !NoRun )
	{
		FString RequiredProduct, FindFolder;
		for( TArray<FString>::TIterator It(Requires); It; ++It )
			if
			(	GConfig->GetString(**It, TEXT("Product"), RequiredProduct, *ConfigFile)
			&&	GetRegisteredProductFolder(RequiredProduct, FindFolder)
			&&	GFileManager->FileSize(*(FindFolder*TEXT("System")*SETUP_INI)) )
			{
				RegistryFolder = FindFolder;
				FolderExists   = 1;
				break;
			}
	}

	// Figure language.
	FString Str;
	if( GConfig->GetString(TEXT("Engine.Engine"),TEXT("Language"),Str,*(RegistryFolder*TEXT("System\\Default.ini"))) )
		UObject::SetLanguage( *Str );
	LanguageChange();

	unguard;
}
void USetupDefinition::CreateRootGroup()
{
	guard(USetupDefinition::CreateRootGroup);
	USetupGroup::Manager = this;
	RootGroup = new(GetOuter(),TEXT("Setup"))USetupGroup;
	unguard;
}
void USetupDefinition::PerformUninstallCopy()
{
	guard(USetupDefinition::PerformUninstallCopy);
	unguard;
}
UBOOL USetupDefinition::GetRegisteredProductFolder( FString Product, FString& Folder )
{
	guard(USetupDefinition::GetRegisteredProductFolder);
	return 0;
	unguard;
}
UBOOL USetupDefinition::LocateSourceFile( FString& Src )
{
	guard(USetupDefinition::LocateSourceFile);
	Src = FString(TEXT("..")) * Src;
	return GFileManager->FileSize(*Src)>=0;
	unguard;
}
void USetupDefinition::Reformat( FString& Msg, TMap<FString,FString>* Map )
{
	if( Map )
		Msg = appFormat( Msg, *Map );
}
FString USetupDefinition::Format( FString Msg, const TCHAR* Other )
{
	guard(USetupDefinition::Format);
	if( Manifest )
	{
		if( Other )
		{
			Reformat( Msg, GConfig->GetSectionPrivate(Other,0,1,*(FString(MANIFEST_FILE)+TEXT(".")+UObject::GetLanguage())) );
			if( FString(UObject::GetLanguage())!=TEXT("INT") )
				Reformat( Msg, GConfig->GetSectionPrivate(Other,0,1,*(FString(MANIFEST_FILE)+TEXT(".INT"))) );
		}
		Reformat( Msg, GConfig->GetSectionPrivate(TEXT("Setup"  ),0,1,*(FString(MANIFEST_FILE)+TEXT(".")+UObject::GetLanguage())) );
		Reformat( Msg, GConfig->GetSectionPrivate(TEXT("General"),0,1,*(FString(MANIFEST_FILE)+TEXT(".")+UObject::GetLanguage())) );
		if( FString(UObject::GetLanguage())!=TEXT("INT") )
		{
			Reformat( Msg, GConfig->GetSectionPrivate(TEXT("Setup"  ),0,1,*(FString(MANIFEST_FILE)+TEXT(".INT"))) );
			Reformat( Msg, GConfig->GetSectionPrivate(TEXT("General"),0,1,*(FString(MANIFEST_FILE)+TEXT(".INT"))) );
		}
		Reformat( Msg, GConfig->GetSectionPrivate(TEXT("Setup"),0,1,*ConfigFile) );
	}
	return Msg;
	unguard;
}
INT USetupDefinition::UpdateRefCount( const TCHAR* Key, const TCHAR* Value, INT Inc )
{
	guard(USetupDefinition::UpdateRefCount);

	// Increment reference count.
	FString  RefKey   = FString(Key) + TEXT(":") + Value;
	FString* CountPtr = RefCounts.Find( *RefKey );
	if( CountPtr || Inc>0 )
	{
		INT Count = (CountPtr ? appAtoi(**CountPtr) : 0) + Inc;
		if( Count>0 )
		{
			RefCounts.Set( *RefKey, *FString::Printf(TEXT("%i"),Count) );
		}
		else
		{
			RefCounts.Remove( *RefKey );
			Count = 0;
		}
		return Count;
	}
	return 0;
	unguard;
}
void USetupDefinition::UninstallLogAdd( const TCHAR* Key, const TCHAR* Value, UBOOL Unique, UBOOL RefLog )
{
	guard(USetupDefinition::UninstallLogAdd);

	// Find in uninstall log.
	if( !RootGroup->UninstallLog.FindPair(Key,Value) )
	{
		// Add to uninstall log.
		if( Unique )
			RootGroup->UninstallLog.Set( Key, Value );
		else
			RootGroup->UninstallLog.Add( Key, Value );
		if( RefLog )
			UpdateRefCount( Key, Value, 1 );
	}
	unguard;
}
void USetupDefinition::LanguageChange()
{
	guard(USetupDefinition::LanguageChange);
	Super::LanguageChange();

	if( !FolderExists )
		RegistryFolder = DefaultFolder;
	if( RegistryFolder.Right(1)==PATH_SEPARATOR )
		RegistryFolder = RegistryFolder.LeftChop(1);
	if( AutoplayWindowTitle==TEXT("") )
		AutoplayWindowTitle = SetupWindowTitle;

	unguard;
}
FString USetupDefinition::GetFullRef( const FString RefFile )
{
	if( RefFile.Left(7)==FString(TEXT("System") PATH_SEPARATOR) )//oldver for Unreal 3dfx version, general multi-reference-path solution?
	{
		FString Test = RefPath * FString(TEXT("System200") PATH_SEPARATOR) + RefFile.Mid(7);
		if( GFileManager->FileSize(*Test)>0 )
			return Test;
	}
	return RefPath * RefFile;
}
void USetupDefinition::DidCancel()
{
	guard(DidCancel);
	appErrorf( LocalizeGeneral(TEXT("DidCancel"))), LocalizeGeneral(TEXT("InstallCancel") );
	unguard;
}
void USetupDefinition::InstallTree( const TCHAR* Action, FInstallPoll* Poll, void (USetupDefinition::*Process)( FString Key, FString Value, UBOOL Selected, FInstallPoll* Poll ), USetupGroup* SetupGroup, UBOOL Selected )
{
	guard(USetupDefinition::InstallTree);
	if( !SetupGroup )
		SetupGroup = RootGroup;

	// Update selection status.
	Selected = Selected && SetupGroup->Selected;

	// Process this item.
	(this->*Process)( TEXT("GroupSpecial"), SetupGroup->GetName(), Selected, Poll );
	TMap<FString,FString>* Map = GConfig->GetSectionPrivate( SetupGroup->GetName(), 0, 1, *ConfigFile );
	check(Map);
	for( TMap<FString,FString>::TIterator It(*Map); It; ++It )
	{
		FString V = Format(It->Value);
		(this->*Process)( It->Key, V, Selected, Poll );
	}

	// Handle all subgroups here.
	for( TArray<USetupGroup*>::TIterator ItG(SetupGroup->Subgroups); ItG; ++ItG )
		InstallTree( Action, Poll, Process, *ItG, Selected );

	unguardf(( TEXT("(%s %s)"), Action, SetupGroup->GetFullName() ));
}
void USetupDefinition::UninstallTree( const TCHAR* Action, FInstallPoll* Poll, void (USetupDefinition::*Process)( FString Key, FString Value, FInstallPoll* Poll ) )
{
	guard(USetupDefinition::UninstallTree);
	for( TArray<USetupGroup*>::TIterator GroupIt(UninstallComponents); GroupIt; ++GroupIt )
	{
		for( TMap<FString,FString>::TIterator ItemIt((*GroupIt)->UninstallLog); ItemIt; ++ItemIt )
			(this->*Process)( ItemIt->Key, ItemIt->Value, Poll );
	}
	unguard;
}
void USetupDefinition::SetupFormatStrings()
{
	guard(USetupDefinition::SetupFormatStrings);

	// Native wildcard strings.
	GConfig->SetString( TEXT("Setup"), TEXT("SrcPath"),  *SrcPath,  *ConfigFile );
	GConfig->SetString( TEXT("Setup"), TEXT("DestPath"), *DestPath, *ConfigFile );
	GConfig->SetString( TEXT("Setup"), TEXT("RefPath"),  *RefPath,  *ConfigFile );
	GConfig->SetString( TEXT("Setup"), TEXT("CdPath"), Patch ? *RefPath : *SrcPath, *ConfigFile );

	unguard;
}
void USetupDefinition::BeginSteps()
{
	guard(USetupDefinition::BeginSteps);

	// Setup the format strings.
	SetupFormatStrings();

	// Empty saved .ini log.
	SavedIni.Empty();

	// Make .ini file.
	SetupIniFile = DestPath * TEXT("System") * SETUP_INI;

	// Load refcounts, if any.
	TMap<FString,FString>* Map = GConfig->GetSectionPrivate( TEXT("RefCounts"), 0, 1, *SetupIniFile );
	if( Map )
		RefCounts = *Map;

	// Load existing log, if any.
	if( Uninstalling )//!!can merge?
	{
		for( TArray<USetupGroup*>::TIterator GroupIt(UninstallComponents); GroupIt; ++GroupIt )
		{
			TMap<FString,FString>* Map = GConfig->GetSectionPrivate( (*GroupIt)->GetName(), 0, 1, *SetupIniFile );
			if( Map )
				(*GroupIt)->UninstallLog = *Map;
		}
	}
	else
	{
		TMap<FString,FString>* Map = GConfig->GetSectionPrivate( *Product, 0, 1, *SetupIniFile );
		if( Map )
			RootGroup->UninstallLog = *Map;
	}

	unguard;
}
void USetupDefinition::EndSteps()
{
	guard(USetupDefinition::EndSteps);

	// Update registry.
	if( Uninstalling )
		for( TArray<USetupGroup*>::TIterator GroupIt(UninstallComponents); GroupIt; ++GroupIt )
			*GConfig->GetSectionPrivate( (*GroupIt)->GetName(), 1, 0, *SetupIniFile ) = (*GroupIt)->UninstallLog;
	else//!!can merge?
		*GConfig->GetSectionPrivate( *Product, 1, 0, *SetupIniFile ) = RootGroup->UninstallLog;

⌨️ 快捷键说明

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