📄 usetupdefinition.cpp
字号:
*GConfig->GetSectionPrivate( TEXT("RefCounts"), 1, 0, *SetupIniFile ) = RefCounts;
GConfig->Flush( 0 );
unguard;
}
void USetupDefinition::DoInstallSteps( FInstallPoll* Poll )
{
guard(USetupDefinition::DoInstallSteps);
// Handle all install steps.
BeginSteps();
TotalBytes = 0;
InstallTree( TEXT("ProcessPreCopy"), Poll, (INSTALL_STEP)ProcessPreCopy );
InstallTree( TEXT("ProcessCopy"), Poll, (INSTALL_STEP)ProcessCopy );
InstallTree( TEXT("ProcessExtra"), Poll, (INSTALL_STEP)ProcessExtra );
InstallTree( TEXT("ProcessPostCopy"), Poll, (INSTALL_STEP)ProcessPostCopy );
Exists = FolderExists = 1;
RegistryFolder = DestPath;
if( IsMasterProduct )
GConfig->SetString( TEXT("Setup"), TEXT("MasterProduct"), *Product, *(DestPath * TEXT("System") * SETUP_INI) );
TMap<FString,FString>* Map = GConfig->GetSectionPrivate( TEXT("Setup"), 1, 0, *(DestPath * TEXT("System") * SETUP_INI) );
Map->AddUnique( TEXT("Group"), *Product );
for( TArray<FSavedIni>::TIterator It(SavedIni); It; ++It )
GConfig->SetString( *It->Section, *It->Key, *It->SavedValue, *It->File );
UninstallLogAdd( TEXT("Caption"), *LocalProduct, 1, 0 );
UninstallLogAdd( TEXT("Version"), *Version, 1, 0 );
for( INT i=0; i<Requires.Num(); i++ )
{
USetupProduct* SetupProduct = new(GetOuter(),*Requires(i))USetupProduct;
if( SetupProduct->Product!=Product )
UninstallLogAdd( TEXT("Requires"), *SetupProduct->Product, 0, 0 );
}
EndSteps();
unguard;
}
void USetupDefinition::DoUninstallSteps( FInstallPoll* Poll )
{
guard(USetupDefinition::DoInstallSteps);
// Handle all uninstall steps.
BeginSteps();
UninstallTotal=0, UninstallCount=0;
UninstallTree( TEXT("ProcessUninstallCountTotal"), Poll, ProcessUninstallCountTotal );
UninstallTree( TEXT("ProcessUninstallRemove"), Poll, ProcessUninstallRemove );
TMap<FString,FString>* Map = GConfig->GetSectionPrivate( TEXT("Setup"), 0, 0, *(DestPath * TEXT("System") * SETUP_INI) );
for( TArray<USetupGroup*>::TIterator GroupIt(UninstallComponents); GroupIt; ++GroupIt )
{
(*GroupIt)->UninstallLog = TMap<FString,FString>();
if( Map )
Map->RemovePair( TEXT("Group"), (*GroupIt)->GetName() );
}
EndSteps();
// If reference counts exausted, delete unnecessary setup file so full directory can be removed.
INT Refs=0;
for( TMap<FString,FString>::TIterator It(RefCounts); It; ++It )
Refs += appAtoi(*It->Value);
if( Refs==0 )
{
GFileManager->Delete( *SetupIniFile );
RemoveEmptyDirectory( *BasePath(SetupIniFile) );
}
unguard;
}
UBOOL USetupDefinition::CheckRequirement( FString Folder, USetupProduct* RequiredProduct, FString& FailMessage )
{
guard(USetupDefinition::CheckRequirement);
// Verify that requirements are met.
FString ExistingVersion;
if( !GConfig->GetString( *RequiredProduct->Product, TEXT("Version"), ExistingVersion, *(Folder + PATH_SEPARATOR TEXT("System") PATH_SEPARATOR SETUP_INI) ) )
{
// See if old version file is there.
if
( RequiredProduct->OldVersionInstallCheck!=TEXT("")
&& GFileManager->FileSize(*(Folder * RequiredProduct->OldVersionInstallCheck))>0 )
{
// Old version found.
ExistingVersion = RequiredProduct->OldVersionNumber;
}
else
{
// Can't install here.
FailMessage = FString::Printf( LocalizeError(TEXT("MissingProduct")), Patch ? LocalizeError(TEXT("MissingProductThis")) : *LocalProduct, *RequiredProduct->Product, *RequiredProduct->Product );
return 0;
}
}
if( appAtoi(*ExistingVersion) < appAtoi(*RequiredProduct->Version) )
{
FailMessage = FString::Printf(LocalizeError(TEXT("OldVersion")), Patch ? LocalizeError(TEXT("MissingProductThis")) : *LocalProduct, *RequiredProduct->Product, appAtoi(*RequiredProduct->Version), appAtoi(*ExistingVersion), *RequiredProduct->Product, appAtoi(*RequiredProduct->Version) );
return 0;
}
return 1;
unguard;
}
UBOOL USetupDefinition::CheckAllRequirements( FString Folder, USetupProduct*& RequiredProduct, FString& FailMessage )
{
guard(USetupDefinition::CheckAllRequirements);
for( TArray<FString>::TIterator It(Requires); It; ++It )
{
RequiredProduct = new(GetOuter(),**It)USetupProduct;
if( !CheckRequirement( Folder, RequiredProduct, FailMessage) )
return 0;
}
return 1;
unguard;
}
// Installation steps.
void USetupDefinition::ProcessCheckRef( FString Key, FString Value, UBOOL Selected, FInstallPoll* Poll )
{
guard(USetupDefinition::ProcessCheckRef);
if( Selected && Key==TEXT("File") )
{
// See whether there is a delta-compression reference.
FFileInfo Info(*Value);
AnyRef = AnyRef || Info.Ref!=TEXT("");
}
unguard;
}
void USetupDefinition::ProcessVerifyCd( FString Key, FString Value, UBOOL Selected, FInstallPoll* Poll )
{
guard(USetupDefinition::ProcessVerifyCd);
if( Selected && Key==TEXT("File") && CdOk==TEXT("") )
{
// Verify existence.
FFileInfo Info(*Value);
if( Info.Lang==TEXT("") || Info.Lang==UObject::GetLanguage() )
if
( Info.Ref!=TEXT("")
&& GFileManager->FileSize(*GetFullRef(*Info.Ref))!=Info.RefSize )
CdOk = Info.Ref;
}
unguard;
}
void USetupDefinition::ProcessPreCopy( FString Key, FString Value, UBOOL Selected, FInstallPoll* Poll )
{
guard(USetupDefinition::ProcessPreCopy);
if( Selected && Key==TEXT("File") )
{
// Verify that file exists and is copyable.
FFileInfo Info(*Value);
if( Info.Lang==TEXT("") || Info.Lang==UObject::GetLanguage() )
{
if( !LocateSourceFile(Info.Src) )
LocalizedFileError( TEXT("MissingInstallerFile"), Patch ? TEXT("AdviseBadDownload") : TEXT("AdviseBadMedia"), *Info.Src );
if( Info.Ref!=TEXT("") )
{
FString FullRef = GetFullRef(*Info.Ref);
if( GFileManager->FileSize(*FullRef)<=0 )
LocalizedFileError( TEXT("MissingReferenceFile"), TEXT("AdviseBadMedia"), *FullRef );
TotalBytes += GFileManager->FileSize(*FullRef);
TotalBytes += Info.Size;
}
else TotalBytes += Info.Size;
}
}
else if( Selected && Key==TEXT("SaveIni") )
{
Value = Format(Value,NULL);
INT Pos = Value.InStr(TEXT(","));
check(Pos>=0);
FString File = DestPath * Value.Left(Pos);
Value = Value.Mid(Pos+1);
Pos = Value.InStrRight(TEXT("."));
check(Pos>=0);
FString Section = Value.Left(Pos);
FString Key = Value.Mid(Pos+1);
if( GFileManager->FileSize(*File)>=0 )
{
GConfig->Detach( *File );
TCHAR IniValue[1024]=TEXT("");
if( GConfig->GetString(*Section,*Key,IniValue,ARRAY_COUNT(IniValue),*File) )
{
new(SavedIni)FSavedIni(File,Section,Key,IniValue);
GConfig->Flush(1,*File);
}
}
}
unguard;
}
void USetupDefinition::ProcessCopy( FString Key, FString Value, UBOOL Selected, FInstallPoll* Poll )
{
guard(USetupDefinition::ProcessCopy);
BYTE Buffer[4096];
if( Selected && Key==TEXT("File") )
{
// Get source and dest filenames.
FFileInfo Info(*Value);
if( Info.Lang==TEXT("") || Info.Lang==UObject::GetLanguage() )
{
if( Info.Dest==TEXT("") )
Info.Dest = Info.Src;
if( !LocateSourceFile(Info.Src) )
LocalizedFileError( TEXT("MissingInstallerFile"), Patch ? TEXT("AdviseBadDownload") : TEXT("AdviseBadMedia"), *Info.Src );
FString FullDest = DestPath * Info.Dest;
FString FullSrc = Info.Ref==TEXT("") ? Info.Src : GetFullRef(*Info.Ref);
FString FullPatch = FullDest + TEXT("_tmp");
// Update uninstallation log.
UninstallLogAdd( TEXT("File"), *Info.Dest, 0, 1 );
// Make destination directory.
if( !GFileManager->MakeDirectory( *BasePath(FullDest), 1 ) )
LocalizedFileError( TEXT("FailedMakeDir"), TEXT("AdviseBadDest"), *FullDest );
// Status display.
if( !Poll->Poll(*FullDest,0,0,RunningBytes,TotalBytes) )
DidCancel();
// Copy SrcAr -> DestAr.
INT CalcOldCRC = 0;
guard(CopyFile);
FString ThisDest = Info.Ref==TEXT("") ? FullDest : FullPatch;
debugf( TEXT("Copying %s to %s"), *FullSrc, *ThisDest);
FArchive* SrcAr = GFileManager->CreateFileReader( *FullSrc );
if( !SrcAr )
LocalizedFileError( TEXT("FailedOpenSource"), Patch ? TEXT("AdviseBadDownload") : TEXT("AdviseBadMedia"), *FullSrc );
INT Size = SrcAr->TotalSize();
FArchive* DestAr = GFileManager->CreateFileWriter( *ThisDest, 1, 1 );
if( !DestAr )
LocalizedFileError( TEXT("FailedOpenDest"), TEXT("AdviseBadDest"), *ThisDest );
for( SQWORD Pos=0; Pos<Size; Pos+=sizeof(Buffer) )
{
INT Count = Min( Size-Pos, (SQWORD)sizeof(Buffer) );
SrcAr->Serialize( Buffer, Count );
if( SrcAr->IsError() )
{
delete SrcAr;
delete DestAr;
LocalizedFileError( TEXT("FailedReadingSource"), Patch ? TEXT("AdviseBadDownload") : TEXT("AdviseBadMedia"), *FullSrc );
}
if( Info.Ref!=TEXT("") )
{
CalcOldCRC = appMemCrc( Buffer, Count, CalcOldCRC );
}
DestAr->Serialize( Buffer, Count );
if( DestAr->IsError() )
{
delete SrcAr;
delete DestAr;
LocalizedFileError( TEXT("FailedWritingDest"), TEXT("AdviseBadDest"), *ThisDest );
}
if( !Poll->Poll(*FullDest,Pos,Size,RunningBytes+=Count,TotalBytes) )
{
delete SrcAr;
delete DestAr;
DidCancel();
}
}
delete SrcAr;
if( !DestAr->Close() )
LocalizedFileError( TEXT("FailedClosingDest"), TEXT("AdviseBadDest"), *ThisDest );
delete DestAr;
unguard;
// Patch SrcAr + DeltaFile -> DestAr.
if( Info.Ref!=TEXT("") )
{
guard(PatchFile);
BYTE Buffer[4096];
// Open files.
FString ThisSrc = FullPatch;
FArchive* SrcAr = GFileManager->CreateFileReader( *ThisSrc );
if( !SrcAr )
LocalizedFileError( TEXT("FailedOpenSource"), Patch ? TEXT("AdviseBadDownload") : TEXT("AdviseBadMedia"), *ThisSrc );
INT Size = SrcAr->TotalSize();
FArchive* DestAr = GFileManager->CreateFileWriter(*FullDest,1,1);
if( !DestAr )
LocalizedFileError( TEXT("FailedOpenDest"), TEXT("AdviseBadDest"), *FullDest );
// Load delta file.
TArray<BYTE> Delta;
FString DeltaName = Info.Src;
if( !appLoadFileToArray( Delta, *DeltaName ) )
LocalizedFileError( TEXT("FailedLoadingUpdate"), TEXT("AdviseBadDownload"), *Info.Src );
debugf( TEXT("Patching %s to %s with %s"), *ThisSrc, *FullDest, *DeltaName );
// Decompress variables.
INT PrevSpot=0, CountSize=0, CRC=0;
INT Magic=0, OldSize=0, OldCRC=0, NewSize=0, NewCRC;
FBufferReader Reader( Delta );
Reader << Magic << OldSize << OldCRC << NewSize << NewCRC;
// Validate.
if( Magic!=0x92f92912 )
appErrorf( LineFormat(LocalizeError("PatchCorrupt")), *DeltaName, LocalizeError("AdviseBadDownload") );
if( OldSize!=Size || OldCRC!=CalcOldCRC )
appErrorf( LocalizeError("CdFileMismatch"), *Info.Ref, *LocalProduct );
// Delta decode it.
INT OldCountSize=0;
while( !Reader.AtEnd() )
{
INT Index;
Reader << AR_INDEX(Index);
if( Index<0 )
{
CRC = appMemCrc( &Delta(Reader.Tell()), -Index, CRC );
DestAr->Serialize( &Delta(Reader.Tell()), -Index );
if( DestAr->IsError() )
LocalizedFileError( TEXT("FailedWritingDest"), TEXT("AdviseBadDest"), *FullDest );
Reader.Seek( Reader.Tell() - Index );
CountSize -= Index;
}
else
{
INT CopyPos;
Reader << AR_INDEX(CopyPos);
CopyPos += PrevSpot;
check(CopyPos>=0);
check(CopyPos+Index<=Size);
SrcAr->Seek( CopyPos );
for( INT Base=Index; Base>0; Base-=sizeof(Buffer) )
{
INT Move = Min(Base,(INT)sizeof(Buffer));
SrcAr->Serialize( Buffer, Move );
if( SrcAr->IsError() )
LocalizedFileError( TEXT("FailedReadingSource"), Patch ? TEXT("AdviseBadDownload") : TEXT("AdviseBadDownload"), *ThisSrc );
CRC = appMemCrc( Buffer, Move, CRC );
DestAr->Serialize( Buffer, Move );
if( DestAr->IsError() )
LocalizedFileError( TEXT("FailedWritingDest"), TEXT("AdviseBadDest"), *FullDest );
}
CountSize += Index;
PrevSpot = CopyPos + Index;
}
if( ((CountSize^OldCountSize)&~(sizeof(Buffer)-1)) || Reader.AtEnd() )
{
if( !Poll->Poll(*FullDest,CountSize,Info.Size,RunningBytes+=(CountSize-OldCountSize),TotalBytes) )
{
delete SrcAr;
delete DestAr;
DidCancel();
}
OldCountSize = CountSize;
}
}
if( NewSize!=CountSize || NewCRC!=CRC )
appErrorf( LineFormat(LocalizeError("PatchCorrupt")), *DeltaName, LocalizeError("AdviseBadDownload") );
delete SrcAr;
if( !DestAr->Close() )
LocalizedFileError( TEXT("FailedClosingDest"), TEXT("AdviseBadDest"), *FullDest );
delete DestAr;
GFileManager->Delete( *ThisSrc );
unguard;
}
}
}
unguard;
}
void USetupDefinition::ProcessExtra( FString Key, FString Value, UBOOL Selected, FInstallPoll* Poll )
{
guard(USetupDefinition::ProcessExtra);
if( Selected && Key==TEXT("Folder") )
{
// Create folders.
FString Path = DestPath * Value;
if( !GFileManager->MakeDirectory( *Path, 1 ) )
LocalizedFileError( TEXT("FailedMakeDir"), TEXT("AdviseBadDest"), *Path );
// Update uninstallation log.
UninstallLogAdd( TEXT("Folder"), *Value, 0, 1 );
}
else if( Selected && (Key==TEXT("Backup") || Key==TEXT("Delete")) )
{
UninstallLogAdd( *Key, *Value, 0, 0 );
}
else if( Key==TEXT("Ini") )
{
if( Value.Left(1)==TEXT("!") )
{
Selected = !Selected;
Value = Value.Mid( 1 );
}
if( Selected )
{
Value = Format(Value,NULL);
INT Pos=Value.InStr(TEXT(","));
check(Pos>=0);
FString IniFile = Value.Left(Pos);
Value = Value.Mid(Pos+1);
Pos = Value.InStr(TEXT("="));
check(Pos>=0);
FString IniValue = Value.Mid(Pos+1);
Value = Value.Left(Pos);
Pos = Value.InStrRight(TEXT("."));
check(Pos>=0);
FString IniSec = Value.Left(Pos);
FString IniKey = Value.Mid(Pos+1);
GConfig->SetString( *IniSec, *IniKey, *IniValue, *(DestPath * IniFile) );
}
}
unguard;
}
void USetupDefinition::ProcessPostCopy( FString Key, FString Value, UBOOL Selected, FInstallPoll* Poll )
{
guard(USetupDefinition::ProcessPostCopy);
if( Key==TEXT("GroupSpecial") && Selected )
UninstallLogAdd( TEXT("DistributionGroup"), *Value, 0, 0 );
unguard;
}
void USetupDefinition::PreExit()
{
guard(USetupDefinition::PreExit);
unguard;
}
// Uninstall steps.
void USetupDefinition::ProcessUninstallCountTotal( FString Key, FString Value, FInstallPoll* Poll )
{
guard(USetupDefinition::ProcessUninstallCountTotal);
UninstallTotal++;
unguard;
}
void USetupDefinition::ProcessUninstallRemove( FString Key, FString Value, FInstallPoll* Poll )
{
guard(USetupDefinition::ProcessUninstallRemove);
Poll->Poll(*Value,0,1,UninstallCount++,UninstallTotal);
if( (Key==TEXT("File") || Key==TEXT("Delete")) && UpdateRefCount(*Key,*Value,-1)==0 )
{
// Delete file; remove folder if empty.
GFileManager->Delete( *(DestPath * Value) );
RemoveEmptyDirectory( *BasePath(DestPath * Value) );
}
else if( Key==TEXT("Folder") && UpdateRefCount(*Key,*Value,-1)==0 )
{
// if folder is empty, remove it.
RemoveEmptyDirectory( *(DestPath * Value) );
}
unguard;
}
IMPLEMENT_CLASS(USetupDefinition);
/*-----------------------------------------------------------------------------
The End.
-----------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -