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 ); TMultiMap<FString,FString>* Map = GConfig->GetSectionPrivate( TEXT("Setup"), 0, 0, *(DestPath * TEXT("System") * SETUP_INI) ); for( TArray<USetupGroup*>::TIterator GroupIt(UninstallComponents); GroupIt; ++GroupIt ) { (*GroupIt)->UninstallLog = TMultiMap<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; }
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; }
std::string paths::PathActors() { return BasePath() + "actors\\";; }
std::string paths::PathSpriteSheets() { return BasePath() + "spritesheets\\"; }
std::string paths::PathTilesets() { return BasePath() + "tilesets\\"; }
std::string paths::PathMaps() { return BasePath() + "tmx_maps\\"; }
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, FILEWRITE_EvenIfReadOnly ); if( !DestAr ) LocalizedFileError( TEXT("FailedOpenDest"), TEXT("AdviseBadDest"), *ThisDest ); if( FullSrc.Right(3).Caps() == TEXT(".UZ") && ThisDest.Right(3).Caps() != TEXT(".UZ")) { INT Signature; FString OrigFilename; *SrcAr << Signature; if( Signature != 5678 ) LocalizedFileError( TEXT("FailedOpenSource"), TEXT("AdviseBadMedia"), *FullSrc ); else { *SrcAr << OrigFilename; FCodecFull Codec; Codec.AddCodec(new FCodecRLE); Codec.AddCodec(new FCodecBWT); Codec.AddCodec(new FCodecMTF); Codec.AddCodec(new FCodecRLE); Codec.AddCodec(new FCodecHuffman); Codec.Decode( *SrcAr, *DestAr ); if( !Poll->Poll(*FullDest,Size,Size,RunningBytes+=Size,TotalBytes) ) { delete SrcAr; delete DestAr; DidCancel(); } } } else { 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,FILEWRITE_EvenIfReadOnly); 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; }