Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/fxcrt/fxcrt_windows.h"
      8 
      9 #include "core/fxcrt/fx_string.h"
     10 
     11 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
     12 
     13 // static
     14 IFXCRT_FileAccess* IFXCRT_FileAccess::Create() {
     15   return new CFXCRT_FileAccess_Win64;
     16 }
     17 
     18 void FXCRT_Windows_GetFileMode(uint32_t dwMode,
     19                                uint32_t& dwAccess,
     20                                uint32_t& dwShare,
     21                                uint32_t& dwCreation) {
     22   dwAccess = GENERIC_READ;
     23   dwShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
     24   if (!(dwMode & FX_FILEMODE_ReadOnly)) {
     25     dwAccess |= GENERIC_WRITE;
     26     dwCreation = (dwMode & FX_FILEMODE_Truncate) ? CREATE_ALWAYS : OPEN_ALWAYS;
     27   } else {
     28     dwCreation = OPEN_EXISTING;
     29   }
     30 }
     31 
     32 #ifdef __cplusplus
     33 extern "C" {
     34 #endif
     35 WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);
     36 WINBASEAPI BOOL WINAPI SetFilePointerEx(HANDLE hFile,
     37                                         LARGE_INTEGER liDistanceToMove,
     38                                         PLARGE_INTEGER lpNewFilePointer,
     39                                         DWORD dwMoveMethod);
     40 #ifdef __cplusplus
     41 }
     42 #endif
     43 
     44 CFXCRT_FileAccess_Win64::CFXCRT_FileAccess_Win64() : m_hFile(nullptr) {}
     45 
     46 CFXCRT_FileAccess_Win64::~CFXCRT_FileAccess_Win64() {
     47   Close();
     48 }
     49 
     50 bool CFXCRT_FileAccess_Win64::Open(const CFX_ByteStringC& fileName,
     51                                    uint32_t dwMode) {
     52   if (m_hFile)
     53     return false;
     54 
     55   uint32_t dwAccess, dwShare, dwCreation;
     56   FXCRT_Windows_GetFileMode(dwMode, dwAccess, dwShare, dwCreation);
     57   m_hFile = ::CreateFileA(fileName.c_str(), dwAccess, dwShare, nullptr,
     58                           dwCreation, FILE_ATTRIBUTE_NORMAL, nullptr);
     59   if (m_hFile == INVALID_HANDLE_VALUE)
     60     m_hFile = nullptr;
     61 
     62   return !!m_hFile;
     63 }
     64 
     65 bool CFXCRT_FileAccess_Win64::Open(const CFX_WideStringC& fileName,
     66                                    uint32_t dwMode) {
     67   if (m_hFile)
     68     return false;
     69 
     70   uint32_t dwAccess, dwShare, dwCreation;
     71   FXCRT_Windows_GetFileMode(dwMode, dwAccess, dwShare, dwCreation);
     72   m_hFile = ::CreateFileW((LPCWSTR)fileName.c_str(), dwAccess, dwShare, nullptr,
     73                           dwCreation, FILE_ATTRIBUTE_NORMAL, nullptr);
     74   if (m_hFile == INVALID_HANDLE_VALUE)
     75     m_hFile = nullptr;
     76 
     77   return !!m_hFile;
     78 }
     79 
     80 void CFXCRT_FileAccess_Win64::Close() {
     81   if (!m_hFile)
     82     return;
     83 
     84   ::CloseHandle(m_hFile);
     85   m_hFile = nullptr;
     86 }
     87 
     88 FX_FILESIZE CFXCRT_FileAccess_Win64::GetSize() const {
     89   if (!m_hFile)
     90     return 0;
     91 
     92   LARGE_INTEGER size = {};
     93   if (!::GetFileSizeEx(m_hFile, &size))
     94     return 0;
     95 
     96   return (FX_FILESIZE)size.QuadPart;
     97 }
     98 
     99 FX_FILESIZE CFXCRT_FileAccess_Win64::GetPosition() const {
    100   if (!m_hFile)
    101     return (FX_FILESIZE)-1;
    102 
    103   LARGE_INTEGER dist = {};
    104   LARGE_INTEGER newPos = {};
    105   if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_CURRENT))
    106     return (FX_FILESIZE)-1;
    107 
    108   return (FX_FILESIZE)newPos.QuadPart;
    109 }
    110 
    111 FX_FILESIZE CFXCRT_FileAccess_Win64::SetPosition(FX_FILESIZE pos) {
    112   if (!m_hFile)
    113     return (FX_FILESIZE)-1;
    114 
    115   LARGE_INTEGER dist;
    116   dist.QuadPart = pos;
    117   LARGE_INTEGER newPos = {};
    118   if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_BEGIN))
    119     return (FX_FILESIZE)-1;
    120 
    121   return (FX_FILESIZE)newPos.QuadPart;
    122 }
    123 
    124 size_t CFXCRT_FileAccess_Win64::Read(void* pBuffer, size_t szBuffer) {
    125   if (!m_hFile)
    126     return 0;
    127 
    128   size_t szRead = 0;
    129   if (!::ReadFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szRead,
    130                   nullptr)) {
    131     return 0;
    132   }
    133   return szRead;
    134 }
    135 
    136 size_t CFXCRT_FileAccess_Win64::Write(const void* pBuffer, size_t szBuffer) {
    137   if (!m_hFile)
    138     return 0;
    139 
    140   size_t szWrite = 0;
    141   if (!::WriteFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szWrite,
    142                    nullptr)) {
    143     return 0;
    144   }
    145   return szWrite;
    146 }
    147 
    148 size_t CFXCRT_FileAccess_Win64::ReadPos(void* pBuffer,
    149                                         size_t szBuffer,
    150                                         FX_FILESIZE pos) {
    151   if (!m_hFile)
    152     return 0;
    153 
    154   if (pos >= GetSize())
    155     return 0;
    156 
    157   if (SetPosition(pos) == (FX_FILESIZE)-1)
    158     return 0;
    159 
    160   return Read(pBuffer, szBuffer);
    161 }
    162 
    163 size_t CFXCRT_FileAccess_Win64::WritePos(const void* pBuffer,
    164                                          size_t szBuffer,
    165                                          FX_FILESIZE pos) {
    166   if (!m_hFile) {
    167     return 0;
    168   }
    169   if (SetPosition(pos) == (FX_FILESIZE)-1) {
    170     return 0;
    171   }
    172   return Write(pBuffer, szBuffer);
    173 }
    174 
    175 bool CFXCRT_FileAccess_Win64::Flush() {
    176   if (!m_hFile)
    177     return false;
    178 
    179   return !!::FlushFileBuffers(m_hFile);
    180 }
    181 
    182 bool CFXCRT_FileAccess_Win64::Truncate(FX_FILESIZE szFile) {
    183   if (SetPosition(szFile) == (FX_FILESIZE)-1)
    184     return false;
    185 
    186   return !!::SetEndOfFile(m_hFile);
    187 }
    188 #endif
    189