diff options
Diffstat (limited to 'core/fxcrt/cfx_fileaccess_windows.cpp')
-rw-r--r-- | core/fxcrt/cfx_fileaccess_windows.cpp | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/core/fxcrt/cfx_fileaccess_windows.cpp b/core/fxcrt/cfx_fileaccess_windows.cpp new file mode 100644 index 0000000000..b39a4d6efc --- /dev/null +++ b/core/fxcrt/cfx_fileaccess_windows.cpp @@ -0,0 +1,196 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fxcrt/cfx_fileaccess_windows.h" + +#include <memory> + +#include "core/fxcrt/fx_string.h" +#include "third_party/base/ptr_util.h" + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + +namespace { + +void GetFileMode(uint32_t dwMode, + uint32_t& dwAccess, + uint32_t& dwShare, + uint32_t& dwCreation) { + dwAccess = GENERIC_READ; + dwShare = FILE_SHARE_READ | FILE_SHARE_WRITE; + if (!(dwMode & FX_FILEMODE_ReadOnly)) { + dwAccess |= GENERIC_WRITE; + dwCreation = (dwMode & FX_FILEMODE_Truncate) ? CREATE_ALWAYS : OPEN_ALWAYS; + } else { + dwCreation = OPEN_EXISTING; + } +} + +} // namespace + +// static +std::unique_ptr<IFX_FileAccess> IFX_FileAccess::Create() { + return pdfium::MakeUnique<CFX_FileAccess_Windows>(); +} + +#ifdef __cplusplus +extern "C" { +#endif +WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize); +WINBASEAPI BOOL WINAPI SetFilePointerEx(HANDLE hFile, + LARGE_INTEGER liDistanceToMove, + PLARGE_INTEGER lpNewFilePointer, + DWORD dwMoveMethod); +#ifdef __cplusplus +} +#endif + +CFX_FileAccess_Windows::CFX_FileAccess_Windows() : m_hFile(nullptr) {} + +CFX_FileAccess_Windows::~CFX_FileAccess_Windows() { + Close(); +} + +bool CFX_FileAccess_Windows::Open(const CFX_ByteStringC& fileName, + uint32_t dwMode) { + if (m_hFile) + return false; + + uint32_t dwAccess, dwShare, dwCreation; + GetFileMode(dwMode, dwAccess, dwShare, dwCreation); + m_hFile = ::CreateFileA(fileName.unterminated_c_str(), dwAccess, dwShare, + nullptr, dwCreation, FILE_ATTRIBUTE_NORMAL, nullptr); + if (m_hFile == INVALID_HANDLE_VALUE) + m_hFile = nullptr; + + return !!m_hFile; +} + +bool CFX_FileAccess_Windows::Open(const CFX_WideStringC& fileName, + uint32_t dwMode) { + if (m_hFile) + return false; + + uint32_t dwAccess, dwShare, dwCreation; + GetFileMode(dwMode, dwAccess, dwShare, dwCreation); + m_hFile = + ::CreateFileW((LPCWSTR)fileName.unterminated_c_str(), dwAccess, dwShare, + nullptr, dwCreation, FILE_ATTRIBUTE_NORMAL, nullptr); + if (m_hFile == INVALID_HANDLE_VALUE) + m_hFile = nullptr; + + return !!m_hFile; +} + +void CFX_FileAccess_Windows::Close() { + if (!m_hFile) + return; + + ::CloseHandle(m_hFile); + m_hFile = nullptr; +} + +FX_FILESIZE CFX_FileAccess_Windows::GetSize() const { + if (!m_hFile) + return 0; + + LARGE_INTEGER size = {}; + if (!::GetFileSizeEx(m_hFile, &size)) + return 0; + + return (FX_FILESIZE)size.QuadPart; +} + +FX_FILESIZE CFX_FileAccess_Windows::GetPosition() const { + if (!m_hFile) + return (FX_FILESIZE)-1; + + LARGE_INTEGER dist = {}; + LARGE_INTEGER newPos = {}; + if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_CURRENT)) + return (FX_FILESIZE)-1; + + return (FX_FILESIZE)newPos.QuadPart; +} + +FX_FILESIZE CFX_FileAccess_Windows::SetPosition(FX_FILESIZE pos) { + if (!m_hFile) + return (FX_FILESIZE)-1; + + LARGE_INTEGER dist; + dist.QuadPart = pos; + LARGE_INTEGER newPos = {}; + if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_BEGIN)) + return (FX_FILESIZE)-1; + + return (FX_FILESIZE)newPos.QuadPart; +} + +size_t CFX_FileAccess_Windows::Read(void* pBuffer, size_t szBuffer) { + if (!m_hFile) + return 0; + + size_t szRead = 0; + if (!::ReadFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szRead, + nullptr)) { + return 0; + } + return szRead; +} + +size_t CFX_FileAccess_Windows::Write(const void* pBuffer, size_t szBuffer) { + if (!m_hFile) + return 0; + + size_t szWrite = 0; + if (!::WriteFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szWrite, + nullptr)) { + return 0; + } + return szWrite; +} + +size_t CFX_FileAccess_Windows::ReadPos(void* pBuffer, + size_t szBuffer, + FX_FILESIZE pos) { + if (!m_hFile) + return 0; + + if (pos >= GetSize()) + return 0; + + if (SetPosition(pos) == (FX_FILESIZE)-1) + return 0; + + return Read(pBuffer, szBuffer); +} + +size_t CFX_FileAccess_Windows::WritePos(const void* pBuffer, + size_t szBuffer, + FX_FILESIZE pos) { + if (!m_hFile) { + return 0; + } + if (SetPosition(pos) == (FX_FILESIZE)-1) { + return 0; + } + return Write(pBuffer, szBuffer); +} + +bool CFX_FileAccess_Windows::Flush() { + if (!m_hFile) + return false; + + return !!::FlushFileBuffers(m_hFile); +} + +bool CFX_FileAccess_Windows::Truncate(FX_FILESIZE szFile) { + if (SetPosition(szFile) == (FX_FILESIZE)-1) + return false; + + return !!::SetEndOfFile(m_hFile); +} +#endif |