diff options
Diffstat (limited to 'zip/ZipArchive/ZipFile_win.cpp')
| -rw-r--r-- | zip/ZipArchive/ZipFile_win.cpp | 261 |
1 files changed, 261 insertions, 0 deletions
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 |
