2024-12-21 10:04:04 +08:00
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
#if defined(PRE_UNZIP_CHANGE)
|
|
|
|
|
|
#include "ZipArchive.h"
|
|
|
|
|
|
#include "LauncherSession.h"
|
|
|
|
|
|
#include "UnZipProcess.h"
|
|
|
|
|
|
|
|
|
|
|
|
extern void TextOut(const TCHAR * format, ...);
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int WINAPI _RunThread(void* pData)
|
|
|
|
|
|
{
|
|
|
|
|
|
CUnZipProcess* pZip = static_cast<CUnZipProcess*>(pData);
|
|
|
|
|
|
pZip->WorkerThread(pZip->GetThreadID());
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CUnZipProcess::CUnZipProcess(CLauncherSession* pSession, LPCTSTR szFilePath, LPCTSTR szFileName)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pLauncherSession = pSession;
|
|
|
|
|
|
_tcscpy_s(m_szOutputFolder, szFilePath);
|
|
|
|
|
|
_tcscpy_s(m_szFileName, szFileName);
|
|
|
|
|
|
|
|
|
|
|
|
m_nThreadCount = 0;
|
|
|
|
|
|
m_nMaxZipFileCount = 0;
|
|
|
|
|
|
m_nUnzipCount = 0;
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD> <20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(CPU<50><55><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> /2 + 1(<28>ִ<EFBFBD> MAX_ZIP_THREAD, <20>ּ<EFBFBD> 2)
|
|
|
|
|
|
_SYSTEM_INFO _Info;
|
|
|
|
|
|
GetSystemInfo(&_Info);
|
|
|
|
|
|
m_nMaxThreadCount = max(_Info.dwNumberOfProcessors/2 + 1, 2);
|
|
|
|
|
|
//<2F>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>
|
|
|
|
|
|
m_nMaxThreadCount = min(m_nMaxThreadCount, MAX_ZIP_THREAD);
|
|
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < m_nMaxThreadCount; i++)
|
|
|
|
|
|
m_hZipEndEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CUnZipProcess::~CUnZipProcess()
|
|
|
|
|
|
{
|
|
|
|
|
|
for(int i = 0; i < m_nMaxThreadCount; i++)
|
|
|
|
|
|
CloseHandle(m_hZipEndEvent[i]);
|
|
|
|
|
|
|
|
|
|
|
|
m_pLauncherSession = NULL;
|
|
|
|
|
|
m_nMaxZipFileCount = 0;
|
|
|
|
|
|
m_nMaxThreadCount = 0;
|
|
|
|
|
|
m_nThreadCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if(!m_ZipLength.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
for(int i = 0; i < (int)m_ZipLength.size();i++)
|
|
|
|
|
|
SAFE_DELETE(m_ZipLength[i]);
|
|
|
|
|
|
m_ZipLength.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_Zip.Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CUnZipProcess::OpenZip()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_Zip.Open(m_szFileName, CZipArchive::zipOpenReadOnly);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CUnZipProcess::UnZip()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_Zip.GetCount() == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
TextOut(_T("Unzip File Counting Failed"));
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_nMaxZipFileCount = m_Zip.GetCount();
|
|
|
|
|
|
|
|
|
|
|
|
//<2F≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>尡 ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>
|
|
|
|
|
|
sZipLength* sZip;
|
|
|
|
|
|
int nCur = 0;
|
|
|
|
|
|
int nStart = 0;
|
|
|
|
|
|
int nEnd = 0;
|
|
|
|
|
|
|
|
|
|
|
|
InitializeCriticalSection(&m_CriticalSection);
|
|
|
|
|
|
//<2F><> <20><><EFBFBD><EFBFBD><EFBFBD>忡 <20>Ҵ<EFBFBD><D2B4><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
int nTerm = MAX_UNZIP_COUNT_IN_THREAD;
|
|
|
|
|
|
if(m_nMaxZipFileCount < (m_nMaxThreadCount * MAX_UNZIP_COUNT_IN_THREAD))
|
|
|
|
|
|
nTerm = m_nMaxZipFileCount / m_nMaxThreadCount;
|
|
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
|
{
|
|
|
|
|
|
for(int k = 0; k < m_nMaxThreadCount;k++)
|
|
|
|
|
|
{
|
|
|
|
|
|
sZip = (sZipLength*)malloc(sizeof(sZipLength));
|
|
|
|
|
|
nStart = (nCur+k) * nTerm;
|
|
|
|
|
|
nEnd = nStart + nTerm;
|
|
|
|
|
|
|
|
|
|
|
|
if(nStart >= m_nMaxZipFileCount)
|
|
|
|
|
|
break;
|
|
|
|
|
|
if(nEnd > m_nMaxZipFileCount)
|
|
|
|
|
|
nEnd = m_nMaxZipFileCount;
|
|
|
|
|
|
|
|
|
|
|
|
sZip->nStart = nStart;
|
|
|
|
|
|
sZip->nEnd = nEnd;
|
|
|
|
|
|
|
|
|
|
|
|
m_ZipLength.push_back(sZip);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(nStart >= m_nMaxZipFileCount)
|
|
|
|
|
|
break;
|
|
|
|
|
|
nCur = nCur + m_nMaxThreadCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UINT tId;
|
|
|
|
|
|
for(int i = 0; i < m_nMaxThreadCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_beginthreadex(NULL, NULL, _RunThread, this, NULL, &tId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
WaitForMultipleObjects(m_nMaxThreadCount, m_hZipEndEvent, TRUE, INFINITE);
|
|
|
|
|
|
DeleteCriticalSection(&m_CriticalSection);
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, ũ<><C5A9> üũ
|
|
|
|
|
|
CZipFileHeader fh;
|
|
|
|
|
|
TCHAR _FilePath[MAX_PATH];
|
|
|
|
|
|
bool IsOk = true;
|
|
|
|
|
|
std::vector<int> _vecRetryZip;
|
|
|
|
|
|
TextOut(_T("UnZip Success, Check Files"));
|
|
|
|
|
|
for(int i = 0;i < m_nMaxZipFileCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_Zip.GetFileInfo(fh, i);
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>丮<EFBFBD><E4B8AE> <20><><EFBFBD><EFBFBD> <20><>ŵ
|
|
|
|
|
|
if(fh.GetOriginalAttributes() & 0x10)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<>ƺ<EFBFBD><C6BA><EFBFBD>
|
|
|
|
|
|
_sntprintf_s(_FilePath, MAX_PATH, _T("%s\\%s"), m_szOutputFolder, (LPCTSTR)fh.GetFileName());
|
|
|
|
|
|
HANDLE hFile = CreateFile(_FilePath, // file to open
|
|
|
|
|
|
GENERIC_READ, // open for reading
|
|
|
|
|
|
FILE_SHARE_READ, // share for reading
|
|
|
|
|
|
NULL, // default security
|
|
|
|
|
|
OPEN_EXISTING, // existing file only
|
|
|
|
|
|
FILE_ATTRIBUTE_NORMAL, // normal file
|
|
|
|
|
|
NULL); // no attr. template
|
|
|
|
|
|
|
|
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
|
|
|
|
{
|
|
|
|
|
|
IsOk = false;
|
|
|
|
|
|
_vecRetryZip.push_back(i);
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD dwSize = GetFileSize(hFile, NULL) ;
|
|
|
|
|
|
// ũ<><C5A9> Ȯ<><C8AE>
|
|
|
|
|
|
if (dwSize == 0xFFFFFFFF || dwSize != fh.m_uUncomprSize) {
|
|
|
|
|
|
_vecRetryZip.push_back(i);
|
|
|
|
|
|
IsOk = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
CloseHandle(hFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>õ<EFBFBD> <20><><EFBFBD>ش<EFBFBD>
|
|
|
|
|
|
if(!IsOk)
|
|
|
|
|
|
{
|
|
|
|
|
|
TextOut(_T("Retry Unzip(Count : %d)"), _vecRetryZip.size());
|
|
|
|
|
|
for(int i = 0; i< (int)_vecRetryZip.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
IsOk = m_Zip.ExtractFile(_vecRetryZip[i], m_szOutputFolder, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch(...)
|
|
|
|
|
|
{
|
|
|
|
|
|
IsOk = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(!IsOk)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_Zip.GetFileInfo(fh, i);
|
|
|
|
|
|
TextOut(_T("%s UnZip Failed"), (LPCTSTR)fh.GetFileName());
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return IsOk;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CUnZipProcess::WorkerThread(int nThreadID)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool IsSuccess;
|
|
|
|
|
|
int nRetry = 0;
|
|
|
|
|
|
|
|
|
|
|
|
CZipArchive zipInThread;
|
|
|
|
|
|
zipInThread.OpenFrom(m_Zip);
|
|
|
|
|
|
sZipLength* sZip;
|
|
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ź<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
// ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD>߿<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>尡 <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
sZip = GetZipLength();
|
|
|
|
|
|
if(sZip == NULL)
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
for(ZIP_INDEX_TYPE i = sZip->nStart; i < sZip->nEnd;i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
nRetry = 0;
|
|
|
|
|
|
while(1)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
IsSuccess = zipInThread.ExtractFile(i, m_szOutputFolder, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch(...)
|
|
|
|
|
|
{
|
|
|
|
|
|
IsSuccess = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(IsSuccess)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_pLauncherSession)
|
|
|
|
|
|
{
|
|
|
|
|
|
CZipFileHeader fh;
|
|
|
|
|
|
zipInThread.GetFileInfo(fh, i);
|
|
|
|
|
|
InterlockedIncrement(&m_nUnzipCount);
|
|
|
|
|
|
#if defined(UNICODE)
|
|
|
|
|
|
m_pLauncherSession->OnUnzip(fh.GetFileName(), m_nUnzipCount, m_nMaxZipFileCount);
|
|
|
|
|
|
#else
|
|
|
|
|
|
WCHAR filename[MAX_PATH];
|
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, fh.GetFileName(), -1, filename, MAX_PATH);
|
|
|
|
|
|
m_pLauncherSession->OnUnzip(filename, m_nUnzipCount, m_nMaxZipFileCount);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
nRetry++;
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD> Ǯ<> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 20ȸ<30><C8B8><EFBFBD><EFBFBD> <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>
|
|
|
|
|
|
if(nRetry > 20)
|
|
|
|
|
|
break;
|
|
|
|
|
|
else
|
|
|
|
|
|
Sleep(50);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
SAFE_DELETE(sZip);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
zipInThread.Close();
|
|
|
|
|
|
|
|
|
|
|
|
SetEvent(m_hZipEndEvent[nThreadID]);
|
|
|
|
|
|
_endthreadex(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif // #if defined(PRE_UNZIP_CHANGE)
|