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

📄 buildintsfx.cpp

📁 zip算法的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -