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

📄 tartool.cpp

📁 一个解压程序,只要设定了解压路径和解压文件的种类,就可以随意解压
💻 CPP
字号:

#include "stdafx.h"
#include "TarTool.h"

struct TarHeader
{
	char filename[100];
	char attrib[8];
	char userID[8];	// 柍帇(^^;
	char groupID[8];// 柍帇(^^;
	char filesize[12];
	char update[12];//峏怴擔帪
	char checksum[8];
	char type;
	char linkedfilename[100];
	char magic_and_ver[8];
	char username[32];	// 柍帇(^^;
	char groupname[32];	// 柍帇(^^;
	char deviceNoM[8];
	char deviceNom[8];
//		埲壓GNU Tar宍幃
	char lastaccessdate[12];
	char creationdate[12];
	char offset[12];
};

static DWORD tar_s2i(char* d,int l)
{
	DWORD s=0;
	for( int i=0; i!=l; i++ )
	{
		if( '0'<=d[i] && d[i]<='7' )
			s = (s<<3)+(d[i]-'0');
		else if( d[i]!=' ' )
			break;
	}
	return s;
}

static bool CheckSum(TarHeader* hd)
{
	BYTE* dat=(BYTE*)hd;
	DWORD sum=0,i=0;
	for( ; i!=148; i++ )sum += dat[i];
	for( ; i!=156; i++ )sum += ' ';
	for( ; i!=512; i++ )sum += dat[i];
	return sum==tar_s2i(hd->checksum,8);
}

bool CTarTool::Check( const char* fname, unsigned long fsize )
{
	if( !TarOpen(fname) )
		return false;
	bool ans=true;

	BYTE hdr[512];
	// 僿僢僟僠僃僢僋
	if( 512!=TarRead(hdr,512) )
		ans=false;
	else
	{
		TarHeader* head=(TarHeader*)hdr;
		if( !CheckSum(head) )
			ans=false;
	}
	TarClose();
	return ans;
}

bool CTarTool::Extract( const char* fname,const char* ddir )
{
	unsigned char* buf = CTool::common_buf;
//--------------------------------------------------------------------//

	if( !TarOpen(fname) )
		return false;

	// 揥奐
	TarHeader* head;
	bool bLongName=false;
	char LongBuf[MAX_PATH];
	BYTE zeroheader[512];
	memset( zeroheader,0,sizeof(zeroheader) );

	char* realfname;
	DWORD realfsize;
	DWORD realattrib;
	DWORD realupdate;
	DWORD realcreatetime;

	while( 512==TarRead(buf,512) )
	{
		// 僿僢僟撉傒崬傒
		head = (TarHeader*)buf;
		if( 0==memcmp( zeroheader,buf,512 ) )
			break;

		// 僼傽僀儖僱乕儉張棟
		if( bLongName )	realfname=LongBuf;
		else			realfname=head->filename;
		bLongName = false;

		// 僽儘僢僋僒僀僘
		realfsize=tar_s2i(head->filesize,12);

		// 僞僀僾偱張棟暘偗
		switch( head->type )
		{
		case '1':
		case '2':
		case '3':
		case '4':
		case '6':
		case '7':
		case 'M':
		case 'S':
		case 'V'://偲傝偁偊偢僴儞僪儕儞僌晄擻偲敾抐偟偨傕偺慡晹
			if( realfsize!=0 )
				SkipBlock( (realfsize>>9)+1 );
			continue;
		case 'L':
		case 'N'://longname
			if( realfsize!=0 && 512==TarRead(buf,512) )
			{
				bLongName=true;
				strncpy(LongBuf,(char*)buf,MAX_PATH);
				SkipBlock( realfsize>>9 );
			}
			continue;
		case '5':
		case 'D'://僨傿儗僋僩儕偩偲巚偆
			realattrib|=(1<<14);
		default:{//揥奐
			realattrib = tar_s2i(head->attrib,8);
			realupdate = tar_s2i(head->update,12);
			if( head->magic_and_ver[6]==' '
			 && head->magic_and_ver[7]==' ' )
				realcreatetime = tar_s2i(head->creationdate,12);
			else
				realcreatetime = realupdate;

			// 僼傽僀儖柤偑曄側傜旘偽偡
			if( *realfname==0 )
			{
				if( realfsize!=0 )
					SkipBlock( (realfsize>>9)+1 );
				continue;
			}

			//by uema2
			char* outname=(char*)LocalAlloc(LPTR, MAX_PATH);
//			char* outname = kiutil::pathMake( realfname );
			TCHAR* t_outname;
			sprintf(outname, "%s\\%s", ueutil::GetExtractPath(),
				kiutil::pathMake( realfname )); // by uema2.

			//僨傿儗僋僩儕儊儞僶偩偭偨傜旘偽偡
			if( realattrib&(1<<14) )
			{
				if( realfsize!=0 )
					SkipBlock( (realfsize>>9)+1 );
				continue;
			}


			FILE* out = fopen( outname,"wb" );
			if( out!=NULL  )
			{
				while( realfsize>>9 )
				{
					TarRead(buf,512);
					fwrite( buf,1,512,out );
					realfsize-=512;
				}
				if( realfsize!=0 )
				{
					TarRead(buf,512);
					fwrite( buf,1,realfsize,out );
				}

				fclose( out );

				kiutil::timeSet( outname,realupdate );

				//outname傪t_outname(TCHAR)偵 by uema2.
				t_outname = (TCHAR*)LocalAlloc(LPTR, (strlen(outname)+1)*sizeof(TCHAR));
				_MultiByteToWideChar(CP_ACP, 0, outname, strlen(outname)+1,
					t_outname, strlen(outname)+1);

//				SetFileAttributes(outname,FILE_ATTRIBUTE_ARCHIVE|
				SetFileAttributes(t_outname,FILE_ATTRIBUTE_ARCHIVE|
					((realattrib&(1<<7))?0:FILE_ATTRIBUTE_READONLY) );
				LocalFree(t_outname); //by uema2.
			}
			else
			{
				// 僄儔乕側傜旘偽偡
				if( realfsize!=0 )
					SkipBlock( (realfsize>>9)+1 );
			}
			LocalFree(outname); //by uema2.
			}break;
		}
	}

	TarClose();
	return true;
}

void CTarTool::SkipBlock(int num)
{
	static char dummy[512];
	for( ; num!=0; num-- )
		TarRead(dummy,512);
}

/******偛偔晛捠側Tar偺Read/Write****************/

bool CTarTool::TarOpen(const char* fname)
{
	TarClose();
	fp = fopen( fname,"rb" );
	return (fp!=NULL);
}

size_t CTarTool::TarRead(void* red,size_t size)
{
	if( fp==NULL )return 0;
	size_t ans=fread( red,1,size,fp );
	return (ans==-1)?0:ans;
}

void CTarTool::TarClose()
{
	if( fp!=NULL )
		fclose(fp),fp=NULL;
}

/*********Tar+Bzip2偺Read****************/

bool CTbzTool::TarOpen(const char* fname)
{
	TarClose();
	bfp=BZ2_bzopen( fname,"rb" );
	return (bfp!=NULL);
}

size_t CTbzTool::TarRead(void* red,size_t size)
{
	if( bfp==NULL )return 0;
	size_t ans=BZ2_bzread( bfp,red,size );
	return (ans==-1)?0:ans;
}

void CTbzTool::TarClose()
{
	if( bfp!=NULL )
		BZ2_bzclose( bfp ),bfp=NULL;
}

/*********Tar+Gzip偺Read*****************/

bool CTgzTool::TarOpen(const char* fname)
{
	TarClose();

	BYTE Magic[10];
	FILE* fp=fopen( fname,"rb" );
	if( 10!=fread(Magic,1,10,fp) )
	{fclose(fp);return false;}
	fclose(fp);
	if( Magic[0]!=0x1f || (Magic[1]!=0x8b && Magic[1]!=0x9e) )
		return false;

	gfp=gzopen( fname,"rb" );
	return (gfp!=NULL);
}

size_t CTgzTool::TarRead(void* red,size_t size)
{
	if( gfp==NULL )return 0;
	size_t ans=gzread( gfp,red,size );
	return (ans==-1)?0:ans;
}

void CTgzTool::TarClose()
{
	if( gfp!=NULL )
		gzclose( gfp ),gfp=NULL;
}

/*********Tar+Compress偺Read*****************/

bool CTaZTool::TarOpen(const char* fname)
{
	TarClose();

	BYTE Magic[10];
	FILE* fp=fopen( fname,"rb" );
	if( 10!=fread(Magic,1,10,fp) )
	{fclose(fp);return false;}
	fclose(fp);
	if( Magic[0]!=0x1f || Magic[1]!=0x9d )
		return false;

	zfp=Z_open( fname,"rb" );
	return (zfp!=NULL);
}

size_t CTaZTool::TarRead(void* red,size_t size)
{
	if( zfp==NULL )return 0;
	size_t ans=Z_read( red,size,zfp );
	return (ans==-1)?0:ans;
}

void CTaZTool::TarClose()
{
	if( zfp!=NULL )
		Z_close( zfp ),zfp=NULL;
}

/*********Tar+Pack偺Read*****************/

bool CTazTool::TarOpen(const char* fname)
{
	TarClose();

	BYTE Magic[10];
	FILE* fp=fopen( fname,"rb" );
	if( 10!=fread(Magic,1,10,fp) )
	{fclose(fp);return false;}
	fclose(fp);
	if( Magic[0]!=0x1f || Magic[1]!=0x1e )
		return false;

	pfp=P_open( fname,"rb" );
	return (pfp!=NULL);
}

size_t CTazTool::TarRead(void* red,size_t size)
{
	if( pfp==NULL )return 0;
	size_t ans=P_read( red,size,pfp );
	return (ans==-1)?0:ans;
}

void CTazTool::TarClose()
{
	if( pfp!=NULL )
		P_close( pfp ),pfp=NULL;
}

⌨️ 快捷键说明

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