summaryrefslogtreecommitdiff
path: root/tools/IM-NG Updater/src/unzipfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/IM-NG Updater/src/unzipfile.cpp')
-rw-r--r--tools/IM-NG Updater/src/unzipfile.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/tools/IM-NG Updater/src/unzipfile.cpp b/tools/IM-NG Updater/src/unzipfile.cpp
new file mode 100644
index 0000000000..6d3057d12d
--- /dev/null
+++ b/tools/IM-NG Updater/src/unzipfile.cpp
@@ -0,0 +1,112 @@
+/*
+Copyright (C) 2012 George Hazan
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include "common.h"
+
+extern "C"
+{
+ #include "Minizip\unzip.h"
+
+ void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def);
+}
+
+bool extractCurrentFile(unzFile uf, TCHAR* ptszDestPath, TCHAR* ptszBackPath)
+{
+ int err = UNZ_OK;
+ unz_file_info64 file_info;
+ char filename[MAX_PATH];
+ char buf[8192];
+
+ err = unzGetCurrentFileInfo64(uf, &file_info, filename, sizeof(filename), buf, sizeof(buf), NULL, 0);
+ if (err != UNZ_OK)
+ return false;
+
+ if (!opts.bUpdateIcons && !_strnicmp(filename, "Icons/", 6))
+ return true;
+
+ TCHAR tszDestFile[MAX_PATH], tszBackFile[MAX_PATH];
+ TCHAR* p = mir_utf8decodeT(filename);
+ if (p == NULL)
+ p = mir_a2t(filename);
+ mir_sntprintf(tszDestFile, SIZEOF(tszDestFile), _T("%s\\%s"), ptszDestPath, p);
+ mir_sntprintf(tszBackFile, SIZEOF(tszBackFile), _T("%s\\%s"), ptszBackPath, p);
+ mir_free(p);
+
+ for (p = tszDestFile; *p; ++p) if (*p == '/') *p = '\\';
+ for (p = tszBackFile; *p; ++p) if (*p == '/') *p = '\\';
+
+ CreatePathToFileT(tszDestFile);
+ CreatePathToFileT(tszBackFile);
+
+ if ( !(file_info.external_fa & FILE_ATTRIBUTE_DIRECTORY)) {
+ err = unzOpenCurrentFile(uf);
+ if (err != UNZ_OK)
+ return false;
+
+ DeleteFile(tszBackFile);
+ MoveFile(tszDestFile, tszBackFile);
+
+ HANDLE hFile = CreateFile(tszDestFile, GENERIC_WRITE, FILE_SHARE_WRITE, 0,
+ CREATE_ALWAYS, file_info.external_fa, 0);
+
+ if (hFile != INVALID_HANDLE_VALUE) {
+ while (true) {
+ err = unzReadCurrentFile(uf, buf, sizeof(buf));
+ if (err <= 0)
+ break;
+
+ DWORD bytes;
+ if (!WriteFile(hFile, buf, err, &bytes, FALSE)) {
+ err = UNZ_ERRNO;
+ break;
+ }
+ }
+
+ FILETIME ftLocal, ftCreate, ftLastAcc, ftLastWrite;
+ GetFileTime(hFile, &ftCreate, &ftLastAcc, &ftLastWrite);
+ DosDateTimeToFileTime(HIWORD(file_info.dosDate), LOWORD(file_info.dosDate), &ftLocal);
+ LocalFileTimeToFileTime(&ftLocal, &ftLastWrite);
+ SetFileTime(hFile, &ftCreate, &ftLastAcc, &ftLastWrite);
+
+ CloseHandle(hFile);
+ unzCloseCurrentFile(uf); /* don't lose the error */
+ }
+ }
+ return true;
+}
+
+bool unzip(const TCHAR* ptszZipFile, TCHAR* ptszDestPath, TCHAR* ptszBackPath)
+{
+ bool bResult = true;
+
+ zlib_filefunc64_def ffunc;
+ fill_fopen64_filefunc(&ffunc);
+
+ unzFile uf = unzOpen2_64(ptszZipFile, &ffunc);
+ if (uf) {
+ do {
+ if ( !extractCurrentFile(uf, ptszDestPath, ptszBackPath))
+ bResult = false;
+ }
+ while (unzGoToNextFile(uf) == UNZ_OK);
+ unzClose(uf);
+ }
+
+ return bResult;
+}