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

📄 selfextractor.cpp

📁 制作自解压文件,此工具不会将资源压缩
💻 CPP
📖 第 1 页 / 共 2 页
字号:
* 
* Parameters: 
*	 int index:		index in array of file
*    CString Dir:	Destination Directory 
* 
* Return: 
*    int: Error Code
*			INPUT_FILE_ERROR	- Failed to open the input file
*			OUTPUT_FILE_ERROR	- Failed to create an output file
*******************************************************************************/
int CSelfExtractor::Extract(int index, CString Dir, 
							funcPtr function /*= NULL*/, void * userData /*= NULL*/)
{
	//Make sure the directory name has a trailing backslash
	EnsureTrailingBackSlash(Dir);

	CFile Thisfile;		//Archive (Usually itself)

	//Read the Table of Contents
	int res = ReadTOC(GetThisFileName());
	if(res != SUCCESS)
		return res;
	
	//Open the archive
	if(!Thisfile.Open(GetThisFileName(), CFile::modeRead))
		return INPUT_FILE_ERROR;
	else
	{
		m_dCurReadSize = 0;

		ExtractOne(&Thisfile, index, Dir, function, userData);

		//Close the archive
		Thisfile.Close();
	}
	return SUCCESS;
}

/*******************************************************************************
* 
* Function: CSelfExtractor::ExtractOne
* 
* Description: 
*	Actual Data Extraction. Seeks to required offset in archive 
*	and writes new file 
* 
* Parameters: 
*    CFile* file:	Pointer to the archive 
*    int index:		Index of file in array 
*    CString Dir:	Destination Dir 
* 
* Return: 
*    int: Error Code
*******************************************************************************/
int CSelfExtractor::ExtractOne(CFile* file, int index, CString Dir, 
							   funcPtr function /*= NULL*/, void * userData /*= NULL*/)
{
	char buffer[1000];	//Buffer to read and write with
	CFile NewFile;		//Extracted File
	
	//Get the file size (in bytes)
	int FileSize = m_InfoArray[index].GetFileSize();

	//Create the new file
	if(!NewFile.Open(Dir + m_InfoArray[index].GetFilename() , CFile::modeCreate | CFile::modeWrite))
		return OUTPUT_FILE_ERROR;
	
	//Seek to the correct Offset
	file->Seek(m_InfoArray[index].GetFileOffset(), CFile::begin);
		
	//Loop the data out from the archive
	DWORD dwWritten = 0;
	DWORD dwRead = 0;
	int AmountToRead = 0;

	while(TRUE)
	{
		//Read out 1000 bytes at a time or the remainder if
		//there is less than 1000 left. Exit if there is none left
		AmountToRead = FileSize - dwWritten;
		if(AmountToRead > 1000)
			AmountToRead = 1000;
		else if(AmountToRead == 0)
		break;

		dwRead = file->Read(buffer, AmountToRead);
		NewFile.Write(buffer, dwRead);
		dwWritten += dwRead;
		m_dCurReadSize = dwWritten;
		
		//Do the callback
		if(function != NULL)
			function(static_cast<void*>(&m_InfoArray[index]), userData);
	}
	//Close the output file
	NewFile.Close();

	return SUCCESS;
}

/*******************************************************************************
* 
* Function: CSelfExtractor::ReadTOC
* 
* Description: 
*	 Read the archive's Table of Contents 
* 
* Parameters: 
*    CString Filename: Filename of the archive (full path) 
* 
* Return: 
*    int: Error Code
*******************************************************************************/
int CSelfExtractor::ReadTOC(CString Filename)
{
	CFile Thisfile;		//Archive file
	char buffer[1000];	//Buffer to read and write with

	//Clear the CSEFileInfo class array
	Reset();
	
	//Open the archive
	if(!Thisfile.Open(Filename, CFile::modeRead))
		return NO_SOURCE;
	else
	{
		//Read in the signature
		Thisfile.Seek(- static_cast<int>(strlen(SIGNATURE)), CFile::end);
		Thisfile.Read(buffer, strlen(SIGNATURE));

		//Check that it matches
		if(strncmp(buffer, SIGNATURE, strlen(SIGNATURE)) != 0)
			return INVALID_SIG;
		else
		{
			//Read Number of files
			int LastOffset = strlen(SIGNATURE) + static_cast<int>(sizeof(int));
			Thisfile.Seek(-LastOffset, CFile::end);
			Thisfile.Read(&m_nFiles, sizeof(int));

			//If there are no files in the archive, there is nothing to extract
			if(m_nFiles == 0)
				return NOTHING_TO_DO;

			//Read the TOC in. The array is filled in reverse to ensure that it 
			//corresponds to the data segment
			for(int i = (m_nFiles - 1); i >= 0 ; i--)
			{
				int nSize	= 0;
				int nOffset = 0;
				int len		= 0;
				LastOffset += sizeof(int);
				
				//Get Length of Pathname
				Thisfile.Seek(-LastOffset, CFile::end);
				Thisfile.Read(&len, sizeof(int));
				LastOffset += len;
				
				//Get Path Name
				Thisfile.Seek(-LastOffset, CFile::end);
				Thisfile.Read(buffer, len);
				LastOffset += sizeof(int);

				//Get File Size
				Thisfile.Seek(-LastOffset, CFile::end);
				Thisfile.Read(&nSize, sizeof(int));
				LastOffset += sizeof(int);

				//Get File Offset
				Thisfile.Seek(-LastOffset, CFile::end);
				Thisfile.Read(&nOffset, sizeof(int));

				//Set the data in the array
				m_InfoArray[i].SetSize(nSize);
				CString Temp(buffer);
				m_InfoArray[i].SetFilename(Temp.Left(len));
				m_InfoArray[i].SetOffset(nOffset);
			}

			//Record the total size of the TOC for use 
			//when extracting the data segment
			m_nTOCSize = LastOffset;
		}
	}
	//Close the archive
	Thisfile.Close();

	return SUCCESS;
}

/*******************************************************************************
* 
* Function: CSelfExtractor::AddFile
* 
* Description: 
*	 Add a file to the archive 
* 
* Parameters: 
*    CString File: Input File path 
* 
* Return: 
*    BOOL: Success or Failure
*******************************************************************************/
BOOL CSelfExtractor::AddFile(CString File)
{
	if(m_nFiles == MAX_FILES)
		return FALSE;

	if(m_InfoArray[m_nFiles].SetData(File))
	{
		m_nFiles++;
		return TRUE;
	}
	
	return FALSE;
}


/*******************************************************************************
* 
* Function: CSelfExtractor::Reset
* 
* Description: 
*	 Reset the CSEFileInfo Array 
* 
* Parameters: 
*    None
* 
* Return: 
*    None
*******************************************************************************/
void CSelfExtractor::Reset()
{
	for(int i = 0; i < MAX_FILES; i++)
		m_InfoArray[i].Reset();

	m_nFiles	= 0;
	m_nTOCSize	= 0;
}

/*******************************************************************************
* 
* Function: CSelfExtractor::EnsureTrailingBackSlash
* 
* Description: 
*	 Ensure that the string has a trailing backslash 
* 
* Parameters: 
*    CString &string: Pathname 
* 
* Return: 
*    CString: Pathname
*******************************************************************************/
CString CSelfExtractor::EnsureTrailingBackSlash(CString &string)
{
	int len = string.GetLength();
	if(string[len - 1] != '\\')
		string += "\\";
	return string;
}

/*******************************************************************************
* 
* Function: CSelfExtractor::GetThisFileName
* 
* Description: 
*	 Get this executable's file path 
* 
* Parameters: 
*    None
* 
* Return: 
*    CString: Full Path for this executable
*******************************************************************************/
CString CSelfExtractor::GetThisFileName()
{
	char FullName[MAX_PATH+1];
	GetModuleFileName(NULL,FullName,MAX_PATH);
	return CString(FullName);
}

/*******************************************************************************
* 
* Function: CSelfExtractor::GetTotalSize
* 
* Description: 
*	 获取文件数组中所有文件SIZE的总和 
* 
* Parameters: 
*    None
* 
* Return: 
*    DWORD: Total Size
*******************************************************************************/
DWORD CSelfExtractor::GetTotalSize()
{
	DWORD dTotal = 0;
	for(int i = 0; i < m_nFiles; i++)
	{
		dTotal += GetFileSize(i);
	}
	return dTotal;
}

⌨️ 快捷键说明

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