From 02d6107c97b48888362e7c6a70dcac323c89d741 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 17 Dec 2023 21:23:58 +0100 Subject: ZipArchive: Update to the 4.6.9 release --- zip/ZipArchive/ZipFile_win.cpp | 261 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 zip/ZipArchive/ZipFile_win.cpp (limited to 'zip/ZipArchive/ZipFile_win.cpp') diff --git a/zip/ZipArchive/ZipFile_win.cpp b/zip/ZipArchive/ZipFile_win.cpp new file mode 100644 index 0000000..df868db --- /dev/null +++ b/zip/ZipArchive/ZipFile_win.cpp @@ -0,0 +1,261 @@ +//////////////////////////////////////////////////////////////////////////////// +// This source file is part of the ZipArchive Library Open Source distribution +// and is Copyrighted 2000 - 2022 by Artpol Software - Tadeusz Dracz +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// For the licensing details refer to the License.txt file. +// +// Web Site: https://www.artpol-software.com +//////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" + +#if _ZIP_FILE_IMPLEMENTATION == ZIP_ZFI_WIN + +#include "ZipFile.h" +#include "ZipException.h" +#include "ZipPathComponent.h" +#include "BitFlag.h" + +#if _MSC_VER < 1300 && !defined INVALID_SET_FILE_POINTER + #define INVALID_SET_FILE_POINTER (DWORD)(-1) +#endif + +CZipFile::CZipFile() +{ + m_hFile = INVALID_HANDLE_VALUE; +} + +CZipFile::CZipFile(LPCTSTR lpszFileName, UINT openFlags) +{ + m_hFile = INVALID_HANDLE_VALUE; + Open(lpszFileName, openFlags, true); +} + +void CZipFile::ThrowError() const +{ + CZipException::Throw(CZipException::fileError, m_szFileName); +} + +bool CZipFile::Open(LPCTSTR lpszFileName, UINT openFlags, bool bThrow) +{ + if (!IsClosed()) + Close(); + + CZipString fileName = lpszFileName; + if (fileName.IsEmpty()) + { + return false; + } + DWORD access; + DWORD temp = openFlags & 3; + if (temp == modeWrite) + { + access = GENERIC_WRITE; + } + else if (temp == modeReadWrite) + { + access = GENERIC_READ | GENERIC_WRITE; + } + else + { + access = GENERIC_READ; + } + + DWORD share; + temp = openFlags & 0x70; + if (temp == shareDenyWrite) + { + share = FILE_SHARE_READ; + } + else if (temp == shareDenyRead) + { + share = FILE_SHARE_WRITE; + } + else if (temp == shareDenyNone) + { + share = FILE_SHARE_READ | FILE_SHARE_WRITE; + } + else + { + share = 0; + } + CZipPathComponent::AddPrefix(fileName, false); + + DWORD create; + if (openFlags & modeCreate) + { + if (openFlags & modeNoTruncate) + { + create = OPEN_ALWAYS; + } + else + { + create = CREATE_ALWAYS; + } + } + else + { + create = OPEN_EXISTING; + } + + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + m_hFile = ::CreateFile(fileName, access, share, &sa, create, FILE_ATTRIBUTE_NORMAL, NULL); + if (m_hFile == INVALID_HANDLE_VALUE) + { + if (bThrow) + ThrowError(); + else + return false; + } + + m_szFileName = lpszFileName; + return true; +} + + +ULONGLONG CZipFile::GetLength() const +{ + ASSERT(m_hFile != INVALID_HANDLE_VALUE); + ULARGE_INTEGER size; + size.LowPart = GetFileSize(m_hFile, &size.HighPart); + if (size.LowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR) + { + ThrowError(); + } + + return size.QuadPart; +} + + +void CZipFile::SetLength(ULONGLONG uNewLen) +{ + ASSERT(m_hFile != INVALID_HANDLE_VALUE); + if (uNewLen > _I64_MAX) + { + CZipException::Throw(CZipException::tooBigSize); + } + Seek(uNewLen, FILE_BEGIN); + if (::SetEndOfFile(m_hFile) == FALSE) + { + ThrowError(); + } +} + +ULONGLONG CZipFile::GetPosition() const +{ + ASSERT(m_hFile != INVALID_HANDLE_VALUE); + + // do not call Seek, to keep GetPosition const +#if (defined(NTDDI_VERSION) && NTDDI_VERSION >=NTDDI_WIN2K) || (_WIN32_WINNT >= 0x0500 && WINVER >= 0x0500) + LARGE_INTEGER li, oli = {0}; + li.QuadPart = (LONGLONG)0; + if (::SetFilePointerEx(m_hFile, li, &oli, FILE_CURRENT) == FALSE) + { + ThrowError(); + } + return oli.QuadPart; +#else + LARGE_INTEGER li; + li.QuadPart = (LONGLONG)0; + li.LowPart = ::SetFilePointer(m_hFile, li.LowPart, &li.HighPart, FILE_CURRENT); + if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) + { + ThrowError(); + } + return li.QuadPart; +#endif +} + +ULONGLONG CZipFile::Seek(LONGLONG dOff, int nFrom) +{ + ASSERT(m_hFile != INVALID_HANDLE_VALUE); + ASSERT(nFrom == FILE_BEGIN || nFrom == FILE_END || nFrom == FILE_CURRENT); + +#if (defined(NTDDI_VERSION) && NTDDI_VERSION >=NTDDI_WIN2K) || (_WIN32_WINNT >= 0x0500 && WINVER >= 0x0500) + + LARGE_INTEGER li, oli = {0}; + li.QuadPart = (LONGLONG)dOff; + if (::SetFilePointerEx(m_hFile, li, &oli, (DWORD)nFrom) == FALSE) + { + ThrowError(); + } + return oli.QuadPart; +#else + LARGE_INTEGER li; + li.QuadPart = (LONGLONG)dOff; + li.LowPart = ::SetFilePointer(m_hFile, li.LowPart, &li.HighPart, (DWORD)nFrom); + if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) + { + ThrowError(); + } + return li.QuadPart; +#endif +} + +void CZipFile::Close() +{ + if (IsClosed()) + return; + bool ok = ::CloseHandle(m_hFile) != FALSE; + m_hFile = INVALID_HANDLE_VALUE; + m_szFileName.Empty(); + if (!ok) + { + ThrowError(); + } +} + +void CZipFile::Flush() +{ + ASSERT(m_hFile != INVALID_HANDLE_VALUE); + if (::FlushFileBuffers(m_hFile) == FALSE) + { + ThrowError(); + } +} + +CZipFile::operator HANDLE() +{ + return m_hFile; +} + + +void CZipFile::Write(const void* lpBuf, size_t nCount) +{ + ASSERT(m_hFile != INVALID_HANDLE_VALUE); + if (nCount == 0) + { + return; + } + DWORD written = 0; + if (::WriteFile(m_hFile, lpBuf, nCount, &written, NULL) == FALSE || written != nCount) + { + ThrowError(); + } +} + +size_t CZipFile::Read(void *lpBuf, size_t nCount) +{ + ASSERT(m_hFile != INVALID_HANDLE_VALUE); + if (nCount == 0) + { + return 0; + } + DWORD read = 0; + if (::ReadFile(m_hFile, lpBuf, nCount, &read, NULL) == FALSE) + { + ThrowError(); + } + return (size_t)read; + +} + +#endif \ No newline at end of file -- cgit v1.2.3