您的位置:首页 > 编程语言

解压7z文件windows代码.

2011-01-29 10:59 239 查看
#include "decode7z.h"

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <tchar.h>
#include <atlbase.h>

extern "C"
{
#include "7z/7z.h"
#include "7z/7zAlloc.h"
#include "7z/7zCrc.h"
#include "7z/7zFile.h"
#include "7z/7zVersion.h"
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//

int cat_path( LPTSTR lpszPath, LPCWSTR lpSubPath )
{
USES_CONVERSION;
PathAppend( lpszPath, CW2CT( lpSubPath ) );
return 0;
}

int save_file( LPCTSTR lpszFile, const void * lpBuf, DWORD dwSize )
{
int nRet = 0;

HANDLE hFile = INVALID_HANDLE_VALUE;

if( 0 == nRet )
{
hFile = CreateFile(
lpszFile,
GENERIC_WRITE,
0,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0 );

if( INVALID_HANDLE_VALUE == hFile )
{
nRet = 1;
}
}

if( 0 == nRet )
{
DWORD dwWrite = 0;

WriteFile( hFile, lpBuf, dwSize, &dwWrite, 0 );

if( dwWrite != dwSize )
{
nRet = 1;
}
}

if( INVALID_HANDLE_VALUE != hFile )
{
CloseHandle( hFile );
hFile = INVALID_HANDLE_VALUE;
}

return nRet;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//

int unzip_7z_file( LPCTSTR lpszInputFile, LPCTSTR lpszOutputPath )
{
USES_CONVERSION;

int nRet = 0;

CFileInStream archiveStream = { 0 };
CLookToRead lookStream = { 0 };
CSzArEx db = { 0 };
ISzAlloc allocImp = { 0 };
ISzAlloc allocTempImp = { 0 };
UInt16 *temp = NULL;
size_t tempSize = 0;

UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0)
Byte *outBuffer = 0;            // it must be 0 before first call for each new archive.
size_t outBufferSize = 0;       // it can have any value before first call (if outBuffer = 0)

////////////////////////////////////////////////////////////
// init

allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;

allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp;

if( 0 == nRet )
{
nRet = InFile_Open( &archiveStream.file, CT2CA( lpszInputFile ) );
}

if( 0 == nRet )
{
FileInStream_CreateVTable(&archiveStream);
LookToRead_CreateVTable(&lookStream, False);

lookStream.realStream = &archiveStream.s;
LookToRead_Init(&lookStream);

CrcGenerateTable();
SzArEx_Init(&db);
}

if( 0 == nRet )
{
nRet = SzArEx_Open( &db, &lookStream.s, &allocImp, &allocTempImp );
}

// 如果没有打开成功,就不会有文件
if( 0 == nRet )
{
for( unsigned int i = 0; i < db.db.NumFiles; ++i )
{
TCHAR szFile[MAX_PATH] = { 0 };
_tcscpy_s( szFile, lpszOutputPath );

size_t offset = 0;
size_t outSizeProcessed = 0;
const CSzFileItem * f = db.db.Files + i;
size_t len = 0;

len = SzArEx_GetFileNameUtf16( &db, i, NULL );

if( len > tempSize )
{
SzFree( NULL, temp );
tempSize = len;

temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));

if (temp == 0)
{
nRet = 1;
break;
}
}

SzArEx_GetFileNameUtf16( &db, i, temp );
cat_path( szFile, ( LPCWSTR )temp );

if( !f->IsDir )
{
nRet = SzArEx_Extract(
&db,
&lookStream.s,
i,
&blockIndex,
&outBuffer,
&outBufferSize,
&offset,
&outSizeProcessed,
&allocImp,
&allocTempImp );

if( 0 != nRet )
{
break;
}
}

for( size_t j = 0; szFile[j] != 0; j++)
{
if( (szFile[j] == '/') || ( szFile[j] == '//' ) )
{
szFile[j] = 0;
CreateDirectory( szFile, 0 );
szFile[j] = CHAR_PATH_SEPARATOR;
}
}

if( f->IsDir )
{
CreateDirectory( szFile, 0 );
}
else
{
nRet = save_file( szFile, outBuffer + offset, outSizeProcessed );
}

if( 0 != nRet )
{
break;
}
}

IAlloc_Free( &allocImp, outBuffer );
}

SzArEx_Free( &db, &allocImp );
SzFree( NULL, temp );
File_Close( &archiveStream.file );

return nRet;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: