#include "PackageFileReader.h" #include "zlib.h" //////////////////////////////////////////////////////////////////////////////// //函数名: 构造函数 //功能: //入口参数: CPackage* pPackage 包文件数据 //出口参数: //说明: //////////////////////////////////////////////////////////////////////////////// CPackageFileReader::CPackageFileReader( CPackage* pPackage, SPackageFileInfo* pPackageFileInfo ) : m_pPackageFileInfo(NULL) , m_pFileBuffer( NULL ) , m_pDecoderBuffer( NULL ) , m_pDecrypteBufferForHeader( NULL ) , m_nCurBufferBegin( 0 ) , m_nBufferSize( 0 ) , m_nCurFilePos( 0 ) , m_nBufferMaxSize( 32 * 1024 ) //32k的大小 , m_bDecrypteBufferForHeaderReady( false ) { if ( !pPackage || !pPackageFileInfo ) { ERROR_PRINT("传入指针不能为空:PACKAGEFILEREADER.CPP-CPackageFileReader",NULL); return; } m_pPackage = pPackage; m_pPackageFileInfo = pPackageFileInfo; ZeroMemory( &m_zipStream, sizeof( m_zipStream ) ); MESSAGE_PRINT("FileReader created!"); } //////////////////////////////////////////////////////////////////////////////// //函数名:析构函数 //功能: //入口参数: //出口参数: //说明: //////////////////////////////////////////////////////////////////////////////// CPackageFileReader::~CPackageFileReader() { DestroyZipStream(); if (m_pPackageFileInfo) { m_pPackageFileInfo = NULL; } if ( m_pFileBuffer ) { delete [] m_pFileBuffer; m_pFileBuffer = NULL; } if ( m_pDecoderBuffer ) { delete [] m_pDecoderBuffer; m_pDecoderBuffer = NULL; } if ( m_pDecrypteBufferForHeader ) { delete [] m_pDecrypteBufferForHeader; m_pDecrypteBufferForHeader = NULL; } MESSAGE_PRINT("PackageFileReader destroyed!"); } //////////////////////////////////////////////////////////////////////////////// //函数名:ReadBuffer //功能:读取指定文件数据 //入口参数: BYTE* pBuffer 目标数据区指针 // SPackageFileInfo* pFileInfo 指定文件描述 //出口参数: UINT 读取数据的真实大小 //说明: pBuffer的空间必须大于等于sFileInfo.OrgSize,否则解压后数据会丢失 //////////////////////////////////////////////////////////////////////////////// UINT CPackageFileReader::ReadBuffer( BYTE* pBuffer) { if (NULL == pBuffer) { ERROR_PRINT("源数据不能为空:PACKAGEFILEREADER.CPP-ReadBuffer",NULL); return 0; } if (NULL == m_pPackage) { ERROR_PRINT("Reader初始化失败:PACKAGEFILEREADER.CPP-ReadBuffer",NULL); return 0; } if (NULL == m_pPackageFileInfo) { ERROR_PRINT("文件描述不能为空:PACKAGEFILEREADER.CPP-ReadBuffer",NULL); return 0; } /*if (_SetReaderFileInfo(pFileInfo) == false) { ERROR_PRINT("设置文件信息出错:PACKAGEFILEREADER.CPP-ReadBuffer"); return 0; }*/ if ( !ReadUnZipBuffer(pBuffer/*, m_pPackageFileInfo*/) ) { ERROR_PRINT("读取文件数据出错:PACKAGEFILEREADER.CPP-ReadBuffer",NULL); return 0; } //包关闭时会关闭包文件,这里不关闭 return _DecodeBuffer( pBuffer,m_pPackageFileInfo ); } UINT CPackageFileReader::ReadBuffer( BYTE * pBuffer, UINT uiBeginPos, UINT uiBytes ) { if (NULL == pBuffer) { ERROR_PRINT("源数据不能为空:PACKAGEFILEREADER.CPP-ReadBuffer",NULL); return 0; } if (NULL == m_pPackage) { ERROR_PRINT("Reader初始化失败:PACKAGEFILEREADER.CPP-ReadBuffer",NULL); return 0; } if (NULL == m_pPackageFileInfo) { ERROR_PRINT("文件描述不能为空:PACKAGEFILEREADER.CPP-ReadBuffer",NULL); return 0; } if ( uiBeginPos >= m_pPackageFileInfo->nFileOrgSize ) { return 0; } if ( m_pPackageFileInfo->eEncryptType == ET_NONE ) { return ReadBufferFromDisk( pBuffer, uiBeginPos, uiBytes ); } else if ( m_pPackageFileInfo->eEncryptType == ET_HEADER ) // { if ( !ReadyBufferDecrypteForHeader() ) return 0; UINT nRealReadBytes = ReadBufferFromDisk( pBuffer, uiBeginPos, uiBytes ); if ( !DoBufferDecrypteForHeader( pBuffer, uiBeginPos, nRealReadBytes ) ) return 0; return nRealReadBytes; } else // zip / zip header { return ReadBufferForDecode( pBuffer, uiBeginPos, uiBytes ); } return 0; } bool CPackageFileReader::ReadyBufferDecrypteForHeader() { if ( m_bDecrypteBufferForHeaderReady ) return true; m_bDecrypteBufferForHeaderReady = true; BYTE buffer[ENCRYPT_PACK_LENGTH]; if ( ReadBufferFromDisk( buffer, 0, ENCRYPT_PACK_LENGTH ) != ENCRYPT_PACK_LENGTH ) { return true; } m_pDecrypteBufferForHeader = new BYTE[ENCRYPT_PACK_LENGTH]; bool bResult = DecryptBuffer( buffer, ENCRYPT_PACK_LENGTH, m_pDecrypteBufferForHeader, ENCRYPT_PACK_LENGTH ); if ( !bResult ) { delete [] m_pDecrypteBufferForHeader; m_pDecrypteBufferForHeader = NULL; } return bResult; } bool CPackageFileReader::DoBufferDecrypteForHeader( BYTE * pBuffer, UINT uiBeginPos, UINT uiBytes ) { if ( !m_pDecrypteBufferForHeader ) return true; if ( uiBeginPos >= ENCRYPT_PACK_LENGTH ) return true; UINT nCopyBytes = ENCRYPT_PACK_LENGTH - uiBeginPos; if ( nCopyBytes > uiBytes ) nCopyBytes = uiBytes; memcpy_s( pBuffer, uiBytes, m_pDecrypteBufferForHeader + uiBeginPos, nCopyBytes ); return true; } UINT CPackageFileReader::ReadBufferForDecode( BYTE * pBuffer, UINT uiBeginPos, UINT uiBytes ) { if ( !m_pFileBuffer ) { m_pFileBuffer = new BYTE[m_nBufferMaxSize]; m_pDecoderBuffer = new BYTE[m_nBufferMaxSize]; } int nLeaveReadByte = (int)m_pPackageFileInfo->nFileOrgSize - (int)uiBeginPos; if ( nLeaveReadByte < 0 ) return 0; nLeaveReadByte = nLeaveReadByte > (int)uiBytes? uiBytes: nLeaveReadByte; int nBufferPos = 0; UINT nBufferBegin = uiBeginPos; while ( nLeaveReadByte > 0 ) { if ( m_nBufferSize == 0 ) //回溯到开始点,准备数据 { if ( !DoDecoderToBuffer( nBufferBegin ) ) return 0; } if ( m_nCurBufferBegin <= nBufferBegin && m_nCurBufferBegin + m_nBufferSize > nBufferBegin ) //在buff中 { int nBufferOffset = nBufferBegin - (int)m_nCurBufferBegin; //如果读到一半,则继续前进读取 int nBufferLeaveSize = m_nBufferMaxSize - nBufferOffset; int nRealReadBufferByte = nLeaveReadByte > nBufferLeaveSize? nBufferLeaveSize: nLeaveReadByte; nLeaveReadByte = nLeaveReadByte - nRealReadBufferByte; memcpy_s( pBuffer + nBufferPos, nRealReadBufferByte, m_pFileBuffer + nBufferOffset, nRealReadBufferByte ); nBufferPos += nRealReadBufferByte; nBufferBegin += nRealReadBufferByte; } else //前进,准备数据 { if ( !DoDecoderToBuffer( nBufferBegin ) ) return 0; } } return nBufferPos; } bool CPackageFileReader::InitZipStream() { m_zipStream.zalloc = (alloc_func)0; m_zipStream.zfree = (free_func)0; m_zipStream.opaque = (voidpf)0; m_zipStream.next_in = m_pDecoderBuffer; m_zipStream.avail_in = 0; m_zipStream.next_out = m_pFileBuffer; int err = inflateInit(&m_zipStream); return err == Z_OK; } void CPackageFileReader::DestroyZipStream() { if ( !m_zipStream.next_in ) inflateEnd(&m_zipStream); } int CPackageFileReader::ReadNextBlockForDecode() { int nOffset = (int)m_nCurFilePos - (int)m_pPackageFileInfo->nPos; int nRealReadByteCount = m_nBufferMaxSize; if ( m_pPackageFileInfo->nFileSize - nOffset < m_nBufferMaxSize ) nRealReadByteCount = m_pPackageFileInfo->nFileSize - nOffset; if ( nRealReadByteCount < 0 ) return 0; //fseek( m_pPackage->GetPackageFile(), m_nCurFilePos, SEEK_SET ); //seek //return (int)fread( m_pDecoderBuffer, 1, nRealReadByteCount, m_pPackage->GetPackageFile() ); return ReadBufferFromDisk( m_pDecoderBuffer, nOffset, nRealReadByteCount ); } bool CPackageFileReader::DoDecoderToBuffer( UINT nNextBufferBeginPos ) { //仅当文件原始大小大于1K才进行解压,否则直接读取 if ( m_pPackageFileInfo->nFileOrgSize >= ZIP_BLOCK_SIZE && ( m_pPackageFileInfo->eEncryptType == ET_ZIP || m_pPackageFileInfo->eEncryptType == ET_ZIP_HEADER ) ) { if ( m_nCurBufferBegin > nNextBufferBeginPos ) //全部清空,重新来找 { m_nCurFilePos = 0; m_nCurBufferBegin = 0; m_nBufferSize = 0; } if ( m_nBufferSize == 0 ) { DestroyZipStream(); InitZipStream(); } if ( m_nCurFilePos == 0 ) { m_nCurFilePos = m_pPackageFileInfo->nPos; } int nCurPos = m_nCurBufferBegin + m_nBufferSize; while ( nCurPos <= (int)nNextBufferBeginPos ) { //fseek( m_pPackage->GetPackageFile(), m_nCurFilePos, SEEK_SET ); //seek int nRealReadByteCount = ReadNextBlockForDecode(); if ( nRealReadByteCount <= 0 ) return false; m_zipStream.total_out = 0; m_zipStream.total_in = 0; m_nCurBufferBegin = nCurPos; while (m_zipStream.total_out < m_nBufferMaxSize ) { if ( m_zipStream.total_in >= m_nBufferMaxSize ) { m_nCurFilePos += m_zipStream.total_in; m_zipStream.total_in = 0; //fseek( m_pPackage->GetPackageFile(), m_nCurFilePos, SEEK_SET ); //seek nRealReadByteCount = ReadNextBlockForDecode(); if ( nRealReadByteCount <= 0 ) return false; } m_zipStream.next_in = m_pDecoderBuffer; m_zipStream.next_out = m_pFileBuffer + m_zipStream.total_out; m_zipStream.avail_in = nRealReadByteCount; m_zipStream.avail_out = m_nBufferMaxSize - m_zipStream.total_out; /* force small buffers */ int err = inflate(&m_zipStream, Z_NO_FLUSH); if (err == Z_STREAM_END) break; if (err != Z_OK ) { return false; } } nCurPos += m_nBufferMaxSize; m_nBufferSize = m_zipStream.total_out; m_nCurFilePos += m_zipStream.total_in; } } else //直接从文件中读取 { m_nCurBufferBegin = nNextBufferBeginPos; m_nBufferSize = ReadBufferFromDisk( m_pFileBuffer, m_nCurBufferBegin, m_nBufferMaxSize ); m_nCurFilePos = ::ftell( m_pPackage->GetPackageFile() ); } return DoBufferDecrypte(); } bool CPackageFileReader::DoBufferDecrypte() { //是否需要解密 //文件大小小于最小解密大小,不解密. if ( ( m_pPackageFileInfo->eEncryptType != ET_HEADER && m_pPackageFileInfo->eEncryptType != ET_ZIP_HEADER ) || m_pPackageFileInfo->nFileOrgSize < ENCRYPT_PACK_LENGTH || m_nBufferSize < ENCRYPT_PACK_LENGTH || m_nCurBufferBegin > ENCRYPT_PACK_LENGTH ) return true; BYTE pDecrypteBuffer[ENCRYPT_PACK_LENGTH]; if ( !DecryptBuffer( m_pFileBuffer,ENCRYPT_PACK_LENGTH, pDecrypteBuffer,ENCRYPT_PACK_LENGTH ) ) { ERROR_PRINT("解密数据出错:PACKAGEFILEREADER.CPP-_DecodeBuffer",NULL); return false; } //拷贝解密数据到源 memcpy_s( m_pFileBuffer,ENCRYPT_PACK_LENGTH,pDecrypteBuffer,ENCRYPT_PACK_LENGTH); return true; } UINT CPackageFileReader::ReadBufferFromDisk( BYTE * pBuffer, UINT uiBeginPos, UINT uiBytes ) { int nLeaveByte = (int)m_pPackageFileInfo->nFileOrgSize - (int)uiBeginPos; if ( nLeaveByte < 0 ) return 0; int nRealByte = nLeaveByte > (int)uiBytes? uiBytes: nLeaveByte; if ( nRealByte == 0 ) return 0; UINT nOffsetPos = m_pPackageFileInfo->nPos; //fseek( m_pPackage->GetPackageFile(), nOffsetPos + uiBeginPos, SEEK_SET ); //return (UINT)fread( pBuffer, 1, nRealByte, m_pPackage->GetPackageFile() ); m_diskFileReader.SetFileInfo( m_pPackage->GetPackageFile(), m_pPackageFileInfo->nFileOrgSize, m_pPackageFileInfo->nPos ); m_diskFileReader.Seek( nOffsetPos + uiBeginPos, SEEK_SET ); return m_diskFileReader.Read( pBuffer, nRealByte ); } //////////////////////////////////////////////////////////////////////////////// //函数名:ReadUnZipBuffer //功能:读取包中数据 //入口参数: BYTE* pBuffer 数据指针 // SPackageFileInfo* pFileInfo 指定文件描述 //出口参数: bool 成功返回ture, 失败返回 false //说明:读取数据不进行解密及解压 //////////////////////////////////////////////////////////////////////////////// bool CPackageFileReader::ReadUnZipBuffer( BYTE* pBuffer/*,SPackageFileInfo* pFileInfo*/) { if ( !m_pPackage) { ERROR_PRINT("Reader未初始化:PACKAGEFILEREADER.CPP-ReadUnZipBuffer",NULL); return false; } FILE* pPackFile = m_pPackage->GetPackageFile(); if ( !pPackFile ) { ERROR_PRINT("包文件未打开:PACKAGEFILEREADER.CPP-ReadUnZipBuffer",NULL); return false; } if (NULL == pBuffer) { ERROR_PRINT("数据buffer不能为空:PACKAGEFILEREADER.CPP-ReadUnZipBuffer",NULL); return false; } if (NULL == m_pPackageFileInfo) { ERROR_PRINT("文件描述不能为空:PACKAGEFILEREADER.CPP-ReadUnZipBuffer",NULL); return false; } /*if (_SetReaderFileInfo(pFileInfo) == false) { ERROR_PRINT("这是Reader失败:PACKAGEFILEREADER.CPP-ReadUnZipBuffer"); return false; }*/ UINT nOffsetPos = m_pPackageFileInfo->nPos; fseek( pPackFile,nOffsetPos,SEEK_SET ); fread( pBuffer, m_pPackageFileInfo->nFileSize,1,pPackFile ); if ( feof(pPackFile) ) { ERROR_PRINT("读取Buffer出错:PACKAGEFILEREADER.CPP-ReadUnZipBuffer",NULL); return false; } //包关闭时会关闭包文件,这里不关闭 return true; } //////////////////////////////////////////////////////////////////////////////// //函数名:_DecodeBuffer //功能: 解压解密数据 //入口参数: BYTE* pBuffer 源数据 // SPackageFileInfo* pFileInfo 源数据描述 //出口参数: UINT 解压解密后的数据大小 //说明:如果失败,返回0 //////////////////////////////////////////////////////////////////////////////// UINT CPackageFileReader::_DecodeBuffer(BYTE* pBuffer, SPackageFileInfo* pFileInfo ) { if (NULL == pBuffer) { ERROR_PRINT("Buffer不能为空:PACKAGEFILEREADER.CPP-_DecodeBuffer",NULL); return 0; } if (NULL == pFileInfo) { ERROR_PRINT("文件描述不能为空:PACKAGEFILEREADER.CPP-_DecodeBuffer",NULL); return 0; } if ( pFileInfo->eEncryptType == ET_NONE ) { return pFileInfo->nFileOrgSize; } UINT nFinalSize = pFileInfo->nFileOrgSize; //首先判断是否需要解压 if ( pFileInfo->eEncryptType == ET_ZIP || pFileInfo->eEncryptType == ET_ZIP_HEADER ) { //仅当文件原始大小大于1K才进行解压 if ( pFileInfo->nFileOrgSize >= ZIP_BLOCK_SIZE ) { BYTE* pUnZipBuffer = new BYTE[pFileInfo->nFileOrgSize]; if ( NULL == pUnZipBuffer ) { ERROR_PRINT("分配内存失败:PACKAGEFILEREADER.CPP-_DecodeBuffer",NULL); return 0; } nFinalSize = UnZipBuffer(pBuffer,pFileInfo->nFileSize,pUnZipBuffer,pFileInfo->nFileOrgSize); if ( nFinalSize == 0 ) { ERROR_PRINT("解压出错:PACKAGEFILEREADER.CPP-_DecodeBuffer",NULL); delete [] pUnZipBuffer; pUnZipBuffer = NULL; return 0; } //删除pBuffer重新,指向解压后的数据 if ( memcpy_s(pBuffer,nFinalSize,pUnZipBuffer,nFinalSize) ) { delete [] pUnZipBuffer; pUnZipBuffer = NULL; ERROR_PRINT("复制解压后数据出错:PACKAGEFILEREADER.CPP-_DecodeBuffer",NULL); return 0; } delete [] pUnZipBuffer; pUnZipBuffer = NULL; } } //是否需要解密 if ( pFileInfo->eEncryptType == ET_HEADER || pFileInfo->eEncryptType == ET_ZIP_HEADER ) { if ( pFileInfo->nFileOrgSize < ENCRYPT_PACK_LENGTH ) { MESSAGE_PRINT("文件大小小于最小解密大小,不解密:PACKAGEFILEREADER.CPP-_DecodeBuffer"); return pFileInfo->nFileOrgSize; } BYTE pDecrypteBuffer[ENCRYPT_PACK_LENGTH]; if ( !DecryptBuffer(pBuffer,ENCRYPT_PACK_LENGTH,pDecrypteBuffer,ENCRYPT_PACK_LENGTH ) ) { ERROR_PRINT("解密数据出错:PACKAGEFILEREADER.CPP-_DecodeBuffer",NULL); return false; } //拷贝解密数据到源 if ( memcpy_s(pBuffer,ENCRYPT_PACK_LENGTH,pDecrypteBuffer,ENCRYPT_PACK_LENGTH) ) { return false; } } return nFinalSize; } //////////////////////////////////////////////////////////////////////////////// //函数名:SetReaderFileInfo //功能: 设置当前读取文件的文件描述 //入口参数: SPackageFileInfo* pFileInfo 源文件描述 //出口参数: 无 //说明: //////////////////////////////////////////////////////////////////////////////// //bool CPackageFileReader::_SetReaderFileInfo(SPackageFileInfo* pFileInfo) //{ // if (NULL == pFileInfo) // { // return false; // } // // m_pPackageFileInfo = pFileInfo; // // return true; //}