📄 buildintsfx.cpp
字号:
try
{
sfxblk = new char[SFXBlkSize + 1];
}
catch( ... )
{
zip->ShowZipMessage(GE_NoMem);
return Result;
}
zip->StartWaitCursor();
// Create a packed byte with various 1 bit settings.
memset(sfxblk, '\0', SFXBlkSize);
strncpy(sfxblk, "MPV", 3);
if(zip->FSFXOptions.Contains(SFXAskCmdLine)) cll = 1; // Don't ask user if he wants to run cmd line.
if(zip->FSFXOptions.Contains(SFXAskFiles)) cll |= 2; // Allow user to edit files in selection box.
if(zip->FSFXOptions.Contains(SFXHideOverWriteBox)) cll |= 4; // Hide overwrite mode box at runtime.
if(zip->FSFXOverWriteMode == OvrAlways) cll |= 8; // Default = ovrConfirm.
if(zip->FSFXOverWriteMode == OvrNever) cll |= 16;
if(!zip->FSFXOptions.Contains(SFXCheckSize)) cll |= 32; // No size checking if false.
if(zip->FSFXOptions.Contains(SFXAutoRun)) cll |= 64; // Use AutoRun if file starts with '!'.
if(zip->FSFXOptions.Contains(SFXNoSuccessMsg)) cll |= 128; // Don't show success message after extraction.
sfxblk[3] = cll;
sfxblk[5] = 1;
sfxblk[6] = Char(LOBYTE(LOWORD(SFXBlkSize)));
sfxblk[7] = Char(HIBYTE(LOWORD(SFXBlkSize)));
int j = zip->FSFXCaption.Length();
sfxblk[8] = (BYTE)j;
StrPCopy(&sfxblk[9], zip->FSFXCaption);
sfxblk[j + 9] = (BYTE)zip->FSFXDefaultDir.Length();
StrPCopy(&sfxblk[j + 10], zip->FSFXDefaultDir);
j += zip->FSFXDefaultDir.Length();
sfxblk[j + 10] = (BYTE)zip->FSFXCommandLine.Length();
StrPCopy(&sfxblk[j + 11], zip->FSFXCommandLine);
j += zip->FSFXCommandLine.Length();
sfxblk[j + 11] = (BYTE)zip->FSFXMessage.Length();
StrPLCopy(&sfxblk[j + 12], zip->FSFXMessage, zip->FSFXMessage.Length());
// Create the destination.
String OutFileName;
// SFX code will be added to a new archive we are
// going to create with an extension of .EXE
if(AutoExeViaAdd) OutFileName = zip->FZipFileName;
else
{
if(UpperCase(ExtractFileExt(zip->FZipFileName)) != ".ZIP")
{
zip->ShowZipMessage(SF_InputIsNoZip);
if(sfxblk) delete[] sfxblk;
zip->StopWaitCursor();
return Result;
}
OutFileName = ChangeFileExt(zip->FZipFileName, ".exe");
}
if(FileExists(OutFileName)) zip->EraseFile(OutFileName, zip->FHowToDelete);
if((OutFile = FileCreate(OutFileName)) != -1)
{
// Copy the SFX code to destination .EXE file.
if((InFile = FileOpen(zip->FSFXPath, fmOpenRead | fmShareDenyWrite )) != -1)
{
Result = zip->CopyBuffer(InFile, OutFile, -1);
SFXSize = FileSeek(InFile, 0, 2);
FileClose(InFile);
// Copy the SFX code to destination .EXE file.
if(!Result && !zip->FSFXIcon->Empty) Result = ReplaceIcon(OutFile, SFXSize);
}
else Result = SE_OpenReadError;
// Copy the special SFX block to the destination.
if(!Result)
{
if(FileWrite(OutFile, sfxblk, SFXBlkSize) != SFXBlkSize) Result = SE_CopyError;
if(!Result)
{
struct ZipEndOfCentral EOC; // We need to create a End-of-central-dir header.
if(AutoExeViaAdd)
{
memset(&EOC, '\0', sizeof(EOC));
EOC.HeaderSig = EndCentralDirSig;
EOC.CentralOffset = SFXSize + SFXBlkSize; // Central offset=EOC offset=end of SFX code.
// Copy the EOC header to the .exe file.
if(FileWrite(OutFile, &EOC, sizeof(EOC)) != sizeof(EOC)) Result = SE_CopyError;
// Let's close the file and get out - we don't
// have a zipfile to append in this case.
}
else
{
// Copy the ZIP file to the destination (BUG fix)
try
{
zip->OpenEOC(EOC, true); // Read the EOC or we get an exception.
FInFileHandle = zip->FInFileHandle; // copy filehandle for internal use
FileSeek(FInFileHandle, 0, 0);
// If we got a warning in List() we assume it's a pre v1.5 .ZIP.
// (converted back from a .EXE ) and we will not change the offsets.
if(zip->FWrongZipStruct)
{
Result = zip->CopyBuffer(FInFileHandle, OutFile, -1);
ZipSize = zip->FRealFileSize;
}
else
{
// Copy until we get at the start of the central header.
if((Result = zip->CopyBuffer(FInFileHandle, OutFile, EOC.CentralOffset)) == 0)
// Now read all headers and change the offsets.
Result = RWCentralDir(OutFile, EOC, SFXSize + SFXBlkSize);
ZipSize = zip->FFileSize;
}
}
catch ( ... )
{
Result = SE_OpenReadError;
}
if(FInFileHandle != -1) FileClose(FInFileHandle);
}
}
}
OutSize = FileSeek(OutFile, 0, 2);
FileClose(OutFile);
}
else Result = SE_CreateError;
if(Result || !AutoExeViaAdd)
{
// An extra check if file is ok.
if(!Result && (SFXSize == -1 || ZipSize == -1 || OutSize == -1 ||
OutSize != SFXSize + ZipSize + SFXBlkSize))
Result = SE_GeneralError;
if(!Result)
{
zip->EraseFile(zip->FZipFileName, zip->FHowToDelete);
zip->ZipFileName = OutFileName; // The .EXE file is now the default archive and invoke List().
}
else DeleteFile(OutFileName);
}
if(sfxblk) delete[] sfxblk;
zip->StopWaitCursor();
return Result;
}
// TInternalSFX::ConvertSFX
// TInternalSFX::ConvertZIP------------------------------------------------------
// Convert an .EXE archive to a .ZIP archive.
// Returns 0 if good, or else a negative error code.
int __fastcall TInternalSFX::ConvertZIP(void)
{
const
SE_CreateError = -1, // Error in creation of OutFile.
SE_CopyError = -2, // Seek error in InFile.
SE_OpenReadError = -3, // Error in open of InFile.
SE_GeneralError = -9,
SE_OutOfMemError = -10;
int OutFile, InSize = -1, OutSize = -1, SFXBlkSize, Result = SE_GeneralError;
char *sfxblk = NULL, *sfxstr, cll;
struct ZipEndOfCentral EOC;
TZipBuilder *zip = dynamic_cast<TZipBuilder *>(FOwner);
// Create the destination.
zip->StartWaitCursor();
Result = SE_CopyError;
String OutFileName = ChangeFileExt(zip->FZipFileName, ".zip");
if(FileExists(OutFileName)) zip->EraseFile(OutFileName, zip->FHowToDelete);
if((OutFile = FileCreate(OutFileName)) != -1)
{
try
{
SFXBlkSize = min(1032, FSFXOffset);
sfxblk = new char[SFXBlkSize];
zip->OpenEOC(EOC, true); // Read the EOC record or we get an exception.
FInFileHandle = zip->FInFileHandle; // copy filehandle for internal use
// Step over SFX code at the begin of the .EXE file
// and read the SFX MPU or MPV block.
if(FileSeek(FInFileHandle, (SeekInt)(FSFXOffset - SFXBlkSize), 0) != -1 &&
FileRead(FInFileHandle, sfxblk, SFXBlkSize) == SFXBlkSize)
{
// Find the start of the MPV or MPU block.
for(int i = 0; i <= SFXBlkSize - 3; i++)
{
if((sfxblk[i] == 'M') && (sfxblk[i + 1] == 'P') && ((sfxblk[i + 2] == 'U') ||
(sfxblk[i + 2] == 'V')))
{
// Read the 'custom' icon back from the executable.
HICON IconHandle = ExtractIcon(HInstance, zip->FZipFileName.c_str(), 0);
if(IconHandle && (int)IconHandle != 1)
{
if(zip->FSFXIcon->Handle) zip->FSFXIcon->ReleaseHandle();
zip->FSFXIcon->Handle = IconHandle;
}
// Read back the original values from the MPU block.
zip->FSFXOptions.Clear();
zip->FSFXOverWriteMode = OvrConfirm;
cll = sfxblk[i + 3];
if(cll & 1) zip->FSFXOptions = zip->FSFXOptions << SFXAskCmdLine;
if(cll & 2) zip->FSFXOptions = zip->FSFXOptions << SFXAskFiles;
if(cll & 4) zip->FSFXOptions = zip->FSFXOptions << SFXHideOverWriteBox;
if(cll & 8) zip->FSFXOverWriteMode = OvrAlways;
if(cll & 16) zip->FSFXOverWriteMode = OvrNever;
if(!(cll & 32)) zip->FSFXOptions = zip->FSFXOptions << SFXCheckSize;
if(cll & 64) zip->FSFXOptions = zip->FSFXOptions << SFXAutoRun;
if(sfxblk[i + 2] == 'U')
{
zip->FSFXCaption = AnsiString(&sfxblk[i+7], sfxblk[i+4]);
zip->FSFXDefaultDir = AnsiString(&sfxblk[sfxblk[i+4] + i+7], sfxblk[i+5]);
zip->FSFXCommandLine = AnsiString(&sfxblk[sfxblk[i+4] + sfxblk[i+5] + i+7], sfxblk[i+6]);
}
else
{
if(cll & 128) zip->FSFXOptions = zip->FSFXOptions << SFXNoSuccessMsg;
sfxstr = &sfxblk[i + 8];
zip->FSFXCaption = AnsiString(&sfxstr[1], sfxstr[0]);
sfxstr = sfxstr + sfxstr[0] + 1;
zip->FSFXDefaultDir = AnsiString(&sfxstr[1], sfxstr[0]);
sfxstr = sfxstr + sfxstr[0] + 1;
zip->FSFXCommandLine = AnsiString(&sfxstr[1], sfxstr[0]);
sfxstr = sfxstr + sfxstr[0] + 1;
zip->FSFXMessage = AnsiString(&sfxstr[1], sfxstr[0]);
}
break;
}
}
// If we got a warning in List() we assume it's a pre v1.5 .EXE.
// and we will not change the offsets.
if(zip->FWrongZipStruct)
{
Result = zip->CopyBuffer(FInFileHandle, OutFile, -1);
InSize = zip->FRealFileSize;
}
else
{
// Copy until the start of the first Central header.
if((Result = zip->CopyBuffer(FInFileHandle, OutFile, EOC.CentralOffset - FSFXOffset )) == 0)
// Now read all headers and change the offsets.
Result = RWCentralDir(OutFile, EOC, -FSFXOffset);
InSize = zip->FFileSize;
}
}
}
catch (const MEMEXCEPT &me)
{ // All memory allocation errors.
Result = SE_OutOfMemError;
}
catch( ... )
{
Result = SE_OpenReadError;
}
if(FInFileHandle != -1) FileClose(FInFileHandle);
OutSize = FileSeek(OutFile, 0, 2);
FileClose(OutFile);
}
else Result = SE_CreateError;
if(!Result && (InSize == -1 || OutSize == -1 || OutSize != InSize - FSFXOffset))
Result = SE_GeneralError;
if(!Result)
{
zip->EraseFile(zip->FZipFileName, zip->FHowToDelete);
zip->ZipFileName = OutFileName; // The .ZIP file is now the default archive and invoke List().
}
else DeleteFile(OutFileName);
if(sfxblk) delete[] sfxblk;
zip->StopWaitCursor();
return Result;
}
// TInternalSFX::ConvertZIP
#endif // INTERNAL_SFX
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -