261 lines
No EOL
11 KiB
C++
261 lines
No EOL
11 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
||
// This source file is part of the ZipArchive library source distribution and
|
||
// is Copyrighted 2000 - 2012 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: http://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) == TRUE;
|
||
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, UINT 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();
|
||
}
|
||
}
|
||
|
||
UINT CZipFile::Read(void *lpBuf, UINT 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 (UINT)read;
|
||
|
||
}
|
||
|
||
#endif |