Пример #1
0
// write a file into ark
// (upon adding, all files flagged as encrypted will be encrypted)
bool ArkFile::WriteFile(const FileEntry& entry)
{
	if( !IsOpen() )
		return false;
	
	// file must be external in order to write it into ark
	if( !entry.IsExternal() )
		return false;
	
	FILE* src_fd = fopen(entry.Filename(), "rb");
	if(src_fd == NULL)
		return false;
	
	bool result = WriteFile(src_fd, entry);
	
	fclose(src_fd);
	return result;
}
Пример #2
0
// reads a file from ark into currently open file descriptor "destFd"
bool ArkFile::ReadFile(FILE* destFd, const FileEntry& entry, bool performDecrypts)
{
	if( !IsOpen() )
		return false;
	
	if(destFd == NULL)
		return false;
	
	// test for possible encrypted song files
	bool is_mogg_file	= performDecrypts && (strstr(entry.Arkname(), ".mogg") != 0);
	bool is_pss_file	= performDecrypts && (strstr(entry.Arkname(), ".pss") != 0);
	bool is_vgs_file	= performDecrypts && (strstr(entry.Arkname(), ".vgs") != 0);
	
	if( entry.IsExternal() )
	{
		// read out file from external file on pc
		FILE* src_fd = fopen(entry.Filename(), "rb");
		if(src_fd == NULL)
			return false;

		s64 filesize;
		if( !performDecrypts && entry.Encrypted() )
		{
			// external file is in decrypted form on pc
			// but is required to be read out in encrypted form
			// this occurs when an external file is added to an ark then the ark is "saved as"
			unsigned char* temp = new unsigned char[(int)entry.Arksize()];
			memcpy(temp, &G_CRYPT_KEY, 4);
			if( fread( temp+4, 1, (int)entry.Filesize(), src_fd) != entry.Filesize() )
			{
				delete[] temp;
				return false;
			}
			if( mNewEncryption )
				dtb_crypt_new(temp, (int)entry.Arksize());
			else
				dtb_crypt_old(temp, (int)entry.Arksize());
			if( fwrite(temp, 1, (int)entry.Arksize(), destFd) != entry.Arksize() )
			{
				delete[] temp;
				return false;
			}
			delete[] temp;
			return true;
		}
		else if( performDecrypts && entry.Encrypted() )
		{
			// external file is in decrypted form on pc
			// but is required to be read out in decrypted form
			// so just read it straight out
			filesize = entry.Filesize();
		}
		else if( !entry.Encrypted() )
		{
			// external file either isnt encrypted
			filesize = entry.Arksize();
		}
		for(s64 i=0; i<filesize; i+=MS_WORK_BUFFER_SIZE)
		{
			int read_size = (int)(min(filesize-i, MS_WORK_BUFFER_SIZE));
			if( fread( mpWorkBuff, 1, read_size, src_fd) != read_size ||
				fwrite(mpWorkBuff, 1, read_size, destFd) != read_size )
			{
				fclose(src_fd);
				return false;
			}
		}
		
		bool read_result = true;
		
		// decrypt output song files if they need to be
		if(is_mogg_file)
		{
			s64 end_file_loc = FTELL64(destFd);
			FSEEK64(destFd, -entry.Arksize(), SEEK_CUR);
			if( IsMoggEncrypted(destFd) )
				read_result = DecryptMogg(destFd);
			else
				FSEEK64(destFd, end_file_loc, SEEK_SET);
		}
		else if(is_pss_file)
		{
			s64 end_file_loc = FTELL64(destFd);
			FSEEK64(destFd, -entry.Arksize(), SEEK_CUR);
			if( IsPssEncrypted(destFd) )
				read_result = DecryptPss(destFd);
			else
				FSEEK64(destFd, end_file_loc, SEEK_SET);
		}
		else if(is_vgs_file)
		{
			s64 end_file_loc = FTELL64(destFd);
			FSEEK64(destFd, -entry.Arksize(), SEEK_CUR);
			if( IsVgsEncrypted(destFd) )
				read_result = DecryptVgs(destFd);
			else
				FSEEK64(destFd, end_file_loc, SEEK_SET);
		}
		
		// close external source file
		fclose(src_fd);
		return read_result;
	}
	else
	{
		// read out file from inside ark file
		FILE* src_fd = GetHandleFromOffset(entry.Offset(), true);
		if(src_fd == NULL)
			return false;
		
		if( performDecrypts && entry.Encrypted() )
		{
			// file needs to be decrypted
			unsigned char* temp = new unsigned char[(int)entry.Arksize()];
			if( fread( temp, 1, (int)entry.Arksize(), src_fd) != entry.Arksize() )
			{
				delete[] temp;
				return false;
			}
			if( mNewEncryption )
				dtb_crypt_new(temp, (int)entry.Arksize());
			else
				dtb_crypt_old(temp, (int)entry.Arksize());
			if( fwrite(temp+4, 1, (int)entry.Filesize(), destFd) != entry.Filesize() )
			{
				delete[] temp;
				return false;
			}
			delete[] temp;
			return true;
		}
		else
		{
			for(s64 i=0; i<entry.Arksize(); i+=MS_WORK_BUFFER_SIZE)
			{
				int read_size = (int)(min(entry.Arksize()-i, MS_WORK_BUFFER_SIZE));
				if( fread( mpWorkBuff, 1, read_size, src_fd) != read_size ||
					fwrite(mpWorkBuff, 1, read_size, destFd) != read_size )
				{
					return false;
				}
			}
			bool read_result = true;
			if(is_mogg_file)
			{
				s64 end_file_loc = FTELL64(destFd);
				FSEEK64(destFd, -entry.Arksize(), SEEK_CUR);
				if( IsMoggEncrypted(destFd) )
					read_result = DecryptMogg(destFd);
				else
					FSEEK64(destFd, end_file_loc, SEEK_SET);
			}
			else if(is_pss_file)
			{
				s64 end_file_loc = FTELL64(destFd);
				FSEEK64(destFd, -entry.Arksize(), SEEK_CUR);
				if( IsPssEncrypted(destFd) )
					read_result = DecryptPss(destFd);
				else
					FSEEK64(destFd, end_file_loc, SEEK_SET);
			}
			else if(is_vgs_file)
			{
				s64 end_file_loc = FTELL64(destFd);
				FSEEK64(destFd, -entry.Arksize(), SEEK_CUR);
				if( IsVgsEncrypted(destFd) )
					read_result = DecryptVgs(destFd);
				else
					FSEEK64(destFd, end_file_loc, SEEK_SET);
			}
			return read_result;
		}
	}
}