mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 13:10:39 +00:00
[ZIPFLDR] Refactor extraction function
Add separate function for a single file extraction. CORE-17796
This commit is contained in:
parent
e6fd41d078
commit
fd441aaae7
2 changed files with 207 additions and 167 deletions
|
@ -344,63 +344,31 @@ public:
|
||||||
PropertySheetW(&psh);
|
PropertySheetW(&psh);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Extract(HWND hDlg, HWND hProgress, const bool* bCancel)
|
eZipExtractError ExtractSingle(
|
||||||
|
HWND hDlg,
|
||||||
|
LPCSTR FullPath,
|
||||||
|
bool is_dir,
|
||||||
|
unz_file_info64* Info,
|
||||||
|
CStringA Name,
|
||||||
|
CStringA Password,
|
||||||
|
bool* bOverwriteAll,
|
||||||
|
const bool* bCancel,
|
||||||
|
int* ErrorCode
|
||||||
|
)
|
||||||
{
|
{
|
||||||
unz_global_info64 gi;
|
int err;
|
||||||
uf = unzOpen2_64(m_Filename.GetString(), &g_FFunc);
|
|
||||||
int err = unzGetGlobalInfo64(uf, &gi);
|
|
||||||
if (err != UNZ_OK)
|
|
||||||
{
|
|
||||||
DPRINT1("ERROR, unzGetGlobalInfo64: 0x%x\n", err);
|
|
||||||
Close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CZipEnumerator zipEnum;
|
|
||||||
if (!zipEnum.initialize(this))
|
|
||||||
{
|
|
||||||
DPRINT1("ERROR, zipEnum.initialize\n");
|
|
||||||
Close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CWindow Progress(hProgress);
|
|
||||||
Progress.SendMessage(PBM_SETRANGE32, 0, gi.number_entry);
|
|
||||||
Progress.SendMessage(PBM_SETPOS, 0, 0);
|
|
||||||
|
|
||||||
BYTE Buffer[2048];
|
BYTE Buffer[2048];
|
||||||
CStringA BaseDirectory = m_Directory;
|
|
||||||
CStringA Name;
|
|
||||||
CStringA Password = m_Password;
|
|
||||||
unz_file_info64 Info;
|
|
||||||
int CurrentFile = 0;
|
|
||||||
bool bOverwriteAll = false;
|
|
||||||
while (zipEnum.next(Name, Info))
|
|
||||||
{
|
|
||||||
if (*bCancel)
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_dir = Name.GetLength() > 0 && Name[Name.GetLength()-1] == '/';
|
|
||||||
|
|
||||||
char CombinedPath[MAX_PATH * 2] = { 0 };
|
|
||||||
PathCombineA(CombinedPath, BaseDirectory, Name);
|
|
||||||
CStringA FullPath = CombinedPath;
|
|
||||||
FullPath.Replace('/', '\\'); /* SHPathPrepareForWriteA does not handle '/' */
|
|
||||||
DWORD dwFlags = SHPPFW_DIRCREATE | (is_dir ? SHPPFW_NONE : SHPPFW_IGNOREFILENAME);
|
DWORD dwFlags = SHPPFW_DIRCREATE | (is_dir ? SHPPFW_NONE : SHPPFW_IGNOREFILENAME);
|
||||||
HRESULT hr = SHPathPrepareForWriteA(hDlg, NULL, FullPath, dwFlags);
|
HRESULT hr = SHPathPrepareForWriteA(hDlg, NULL, FullPath, dwFlags);
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
{
|
{
|
||||||
Close();
|
*ErrorCode = hr;
|
||||||
return false;
|
return eDirectoryError;
|
||||||
}
|
}
|
||||||
CurrentFile++;
|
|
||||||
if (is_dir)
|
if (is_dir)
|
||||||
continue;
|
return eNoError;
|
||||||
|
|
||||||
if (Info.flag & MINIZIP_PASSWORD_FLAG)
|
if (Info->flag & MINIZIP_PASSWORD_FLAG)
|
||||||
{
|
{
|
||||||
eZipPasswordResponse Response = eAccept;
|
eZipPasswordResponse Response = eAccept;
|
||||||
do
|
do
|
||||||
|
@ -428,13 +396,11 @@ public:
|
||||||
|
|
||||||
if (Response == eSkip)
|
if (Response == eSkip)
|
||||||
{
|
{
|
||||||
Progress.SendMessage(PBM_SETPOS, CurrentFile, 0);
|
return eNoError;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else if (Response == eAbort)
|
else if (Response == eAbort)
|
||||||
{
|
{
|
||||||
Close();
|
return eExtractAbort;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -445,8 +411,8 @@ public:
|
||||||
if (err != UNZ_OK)
|
if (err != UNZ_OK)
|
||||||
{
|
{
|
||||||
DPRINT1("ERROR, unzOpenCurrentFilePassword: 0x%x\n", err);
|
DPRINT1("ERROR, unzOpenCurrentFilePassword: 0x%x\n", err);
|
||||||
Close();
|
*ErrorCode = err;
|
||||||
return false;
|
return eOpenError;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE hFile = CreateFileA(FullPath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
HANDLE hFile = CreateFileA(FullPath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
@ -455,14 +421,15 @@ public:
|
||||||
DWORD dwErr = GetLastError();
|
DWORD dwErr = GetLastError();
|
||||||
if (dwErr == ERROR_FILE_EXISTS)
|
if (dwErr == ERROR_FILE_EXISTS)
|
||||||
{
|
{
|
||||||
bool bOverwrite = bOverwriteAll;
|
bool bOverwrite = *bOverwriteAll;
|
||||||
if (!bOverwriteAll)
|
if (!*bOverwriteAll)
|
||||||
{
|
{
|
||||||
eZipConfirmResponse Result = _CZipAskReplace(hDlg, FullPath);
|
eZipConfirmResponse Result = _CZipAskReplace(hDlg, FullPath);
|
||||||
switch (Result)
|
switch (Result)
|
||||||
{
|
{
|
||||||
case eYesToAll:
|
case eYesToAll:
|
||||||
bOverwriteAll = true;
|
*bOverwriteAll = true;
|
||||||
|
/* fall through */
|
||||||
case eYes:
|
case eYes:
|
||||||
bOverwrite = true;
|
bOverwrite = true;
|
||||||
break;
|
break;
|
||||||
|
@ -470,8 +437,7 @@ public:
|
||||||
break;
|
break;
|
||||||
case eCancel:
|
case eCancel:
|
||||||
unzCloseCurrentFile(uf);
|
unzCloseCurrentFile(uf);
|
||||||
Close();
|
return eExtractAbort;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,15 +452,15 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unzCloseCurrentFile(uf);
|
unzCloseCurrentFile(uf);
|
||||||
continue;
|
return eNoError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
unzCloseCurrentFile(uf);
|
unzCloseCurrentFile(uf);
|
||||||
DPRINT1("ERROR, CreateFileA: 0x%x (%s)\n", dwErr, bOverwriteAll ? "Y" : "N");
|
DPRINT1("ERROR, CreateFileA: 0x%x (%s)\n", dwErr, *bOverwriteAll ? "Y" : "N");
|
||||||
Close();
|
*ErrorCode = dwErr;
|
||||||
return false;
|
return eFileError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,10 +470,9 @@ public:
|
||||||
{
|
{
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
BOOL deleteResult = DeleteFileA(FullPath);
|
BOOL deleteResult = DeleteFileA(FullPath);
|
||||||
if (deleteResult == 0)
|
if (!deleteResult)
|
||||||
DPRINT1("ERROR, DeleteFileA: 0x%x\n", GetLastError());
|
DPRINT1("ERROR, DeleteFileA: 0x%x\n", GetLastError());
|
||||||
Close();
|
return eExtractAbort;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = unzReadCurrentFile(uf, Buffer, sizeof(Buffer));
|
err = unzReadCurrentFile(uf, Buffer, sizeof(Buffer));
|
||||||
|
@ -536,7 +501,7 @@ public:
|
||||||
|
|
||||||
/* Update Filetime */
|
/* Update Filetime */
|
||||||
FILETIME LocalFileTime;
|
FILETIME LocalFileTime;
|
||||||
DosDateTimeToFileTime((WORD)(Info.dosDate >> 16), (WORD)Info.dosDate, &LocalFileTime);
|
DosDateTimeToFileTime((WORD)(Info->dosDate >> 16), (WORD)Info->dosDate, &LocalFileTime);
|
||||||
FILETIME FileTime;
|
FILETIME FileTime;
|
||||||
LocalFileTimeToFileTime(&LocalFileTime, &FileTime);
|
LocalFileTimeToFileTime(&LocalFileTime, &FileTime);
|
||||||
SetFileTime(hFile, &FileTime, &FileTime, &FileTime);
|
SetFileTime(hFile, &FileTime, &FileTime, &FileTime);
|
||||||
|
@ -548,8 +513,8 @@ public:
|
||||||
{
|
{
|
||||||
unzCloseCurrentFile(uf);
|
unzCloseCurrentFile(uf);
|
||||||
DPRINT1("ERROR, unzReadCurrentFile2: 0x%x\n", err);
|
DPRINT1("ERROR, unzReadCurrentFile2: 0x%x\n", err);
|
||||||
Close();
|
*ErrorCode = err;
|
||||||
return false;
|
return eUnpackError;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -559,6 +524,71 @@ public:
|
||||||
DPRINT1("ERROR(non-fatal), unzCloseCurrentFile: 0x%x\n", err);
|
DPRINT1("ERROR(non-fatal), unzCloseCurrentFile: 0x%x\n", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return eNoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Extract(HWND hDlg, HWND hProgress, const bool* bCancel)
|
||||||
|
{
|
||||||
|
unz_global_info64 gi;
|
||||||
|
uf = unzOpen2_64(m_Filename.GetString(), &g_FFunc);
|
||||||
|
int err = unzGetGlobalInfo64(uf, &gi);
|
||||||
|
if (err != UNZ_OK)
|
||||||
|
{
|
||||||
|
DPRINT1("ERROR, unzGetGlobalInfo64: 0x%x\n", err);
|
||||||
|
Close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CZipEnumerator zipEnum;
|
||||||
|
if (!zipEnum.initialize(this))
|
||||||
|
{
|
||||||
|
DPRINT1("ERROR, zipEnum.initialize\n");
|
||||||
|
Close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWindow Progress(hProgress);
|
||||||
|
Progress.SendMessage(PBM_SETRANGE32, 0, gi.number_entry);
|
||||||
|
Progress.SendMessage(PBM_SETPOS, 0, 0);
|
||||||
|
|
||||||
|
CStringA BaseDirectory = m_Directory;
|
||||||
|
CStringA Name;
|
||||||
|
CStringA Password = m_Password;
|
||||||
|
unz_file_info64 Info;
|
||||||
|
int CurrentFile = 0;
|
||||||
|
bool bOverwriteAll = false;
|
||||||
|
while (zipEnum.next(Name, Info))
|
||||||
|
{
|
||||||
|
if (*bCancel)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_dir = Name.GetLength() > 0 && Name[Name.GetLength()-1] == '/';
|
||||||
|
|
||||||
|
char CombinedPath[MAX_PATH * 2] = { 0 };
|
||||||
|
PathCombineA(CombinedPath, BaseDirectory, Name);
|
||||||
|
CStringA FullPath = CombinedPath;
|
||||||
|
FullPath.Replace('/', '\\'); /* SHPathPrepareForWriteA does not handle '/' */
|
||||||
|
eZipExtractError Result = ExtractSingle(hDlg, FullPath, is_dir, &Info, Name, Password, &bOverwriteAll, bCancel, &err);
|
||||||
|
if (Result != eDirectoryError)
|
||||||
|
CurrentFile++;
|
||||||
|
switch (Result)
|
||||||
|
{
|
||||||
|
case eNoError:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eExtractAbort:
|
||||||
|
case eDirectoryError:
|
||||||
|
case eFileError:
|
||||||
|
case eOpenError:
|
||||||
|
case eUnpackError:
|
||||||
|
Close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Result == eNoError && is_dir)
|
||||||
|
continue;
|
||||||
Progress.SendMessage(PBM_SETPOS, CurrentFile, 0);
|
Progress.SendMessage(PBM_SETPOS, CurrentFile, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,16 @@ enum eZipConfirmResponse
|
||||||
|
|
||||||
eZipConfirmResponse _CZipAskReplace(HWND hDlg, const char* FullPath);
|
eZipConfirmResponse _CZipAskReplace(HWND hDlg, const char* FullPath);
|
||||||
|
|
||||||
|
enum eZipExtractError
|
||||||
|
{
|
||||||
|
eNoError,
|
||||||
|
eExtractAbort,
|
||||||
|
eDirectoryError,
|
||||||
|
eFileError,
|
||||||
|
eOpenError,
|
||||||
|
eUnpackError,
|
||||||
|
};
|
||||||
|
|
||||||
#include "CZipEnumerator.hpp"
|
#include "CZipEnumerator.hpp"
|
||||||
#include "CZipFolder.hpp"
|
#include "CZipFolder.hpp"
|
||||||
#include "CZipCreator.hpp"
|
#include "CZipCreator.hpp"
|
||||||
|
|
Loading…
Reference in a new issue