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/cfx_fileaccess_windows.h" 8 9 #include <memory> 10 11 #include "core/fxcrt/fx_string.h" 12 #include "third_party/base/ptr_util.h" 13 14 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ 15 16 namespace { 17 18 void 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 } // namespace 33 34 // static 35 std::unique_ptr<IFX_FileAccess> IFX_FileAccess::Create() { 36 return pdfium::MakeUnique<CFX_FileAccess_Windows>(); 37 } 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize); 43 WINBASEAPI BOOL WINAPI SetFilePointerEx(HANDLE hFile, 44 LARGE_INTEGER liDistanceToMove, 45 PLARGE_INTEGER lpNewFilePointer, 46 DWORD dwMoveMethod); 47 #ifdef __cplusplus 48 } 49 #endif 50 51 CFX_FileAccess_Windows::CFX_FileAccess_Windows() : m_hFile(nullptr) {} 52 53 CFX_FileAccess_Windows::~CFX_FileAccess_Windows() { 54 Close(); 55 } 56 57 bool CFX_FileAccess_Windows::Open(const ByteStringView& fileName, 58 uint32_t dwMode) { 59 if (m_hFile) 60 return false; 61 62 uint32_t dwAccess, dwShare, dwCreation; 63 GetFileMode(dwMode, dwAccess, dwShare, dwCreation); 64 m_hFile = ::CreateFileA(fileName.unterminated_c_str(), dwAccess, dwShare, 65 nullptr, dwCreation, FILE_ATTRIBUTE_NORMAL, nullptr); 66 if (m_hFile == INVALID_HANDLE_VALUE) 67 m_hFile = nullptr; 68 69 return !!m_hFile; 70 } 71 72 bool CFX_FileAccess_Windows::Open(const WideStringView& fileName, 73 uint32_t dwMode) { 74 if (m_hFile) 75 return false; 76 77 uint32_t dwAccess, dwShare, dwCreation; 78 GetFileMode(dwMode, dwAccess, dwShare, dwCreation); 79 m_hFile = 80 ::CreateFileW((LPCWSTR)fileName.unterminated_c_str(), dwAccess, dwShare, 81 nullptr, dwCreation, FILE_ATTRIBUTE_NORMAL, nullptr); 82 if (m_hFile == INVALID_HANDLE_VALUE) 83 m_hFile = nullptr; 84 85 return !!m_hFile; 86 } 87 88 void CFX_FileAccess_Windows::Close() { 89 if (!m_hFile) 90 return; 91 92 ::CloseHandle(m_hFile); 93 m_hFile = nullptr; 94 } 95 96 FX_FILESIZE CFX_FileAccess_Windows::GetSize() const { 97 if (!m_hFile) 98 return 0; 99 100 LARGE_INTEGER size = {}; 101 if (!::GetFileSizeEx(m_hFile, &size)) 102 return 0; 103 104 return (FX_FILESIZE)size.QuadPart; 105 } 106 107 FX_FILESIZE CFX_FileAccess_Windows::GetPosition() const { 108 if (!m_hFile) 109 return (FX_FILESIZE)-1; 110 111 LARGE_INTEGER dist = {}; 112 LARGE_INTEGER newPos = {}; 113 if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_CURRENT)) 114 return (FX_FILESIZE)-1; 115 116 return (FX_FILESIZE)newPos.QuadPart; 117 } 118 119 FX_FILESIZE CFX_FileAccess_Windows::SetPosition(FX_FILESIZE pos) { 120 if (!m_hFile) 121 return (FX_FILESIZE)-1; 122 123 LARGE_INTEGER dist; 124 dist.QuadPart = pos; 125 LARGE_INTEGER newPos = {}; 126 if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_BEGIN)) 127 return (FX_FILESIZE)-1; 128 129 return (FX_FILESIZE)newPos.QuadPart; 130 } 131 132 size_t CFX_FileAccess_Windows::Read(void* pBuffer, size_t szBuffer) { 133 if (!m_hFile) 134 return 0; 135 136 size_t szRead = 0; 137 if (!::ReadFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szRead, 138 nullptr)) { 139 return 0; 140 } 141 return szRead; 142 } 143 144 size_t CFX_FileAccess_Windows::Write(const void* pBuffer, size_t szBuffer) { 145 if (!m_hFile) 146 return 0; 147 148 size_t szWrite = 0; 149 if (!::WriteFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szWrite, 150 nullptr)) { 151 return 0; 152 } 153 return szWrite; 154 } 155 156 size_t CFX_FileAccess_Windows::ReadPos(void* pBuffer, 157 size_t szBuffer, 158 FX_FILESIZE pos) { 159 if (!m_hFile) 160 return 0; 161 162 if (pos >= GetSize()) 163 return 0; 164 165 if (SetPosition(pos) == (FX_FILESIZE)-1) 166 return 0; 167 168 return Read(pBuffer, szBuffer); 169 } 170 171 size_t CFX_FileAccess_Windows::WritePos(const void* pBuffer, 172 size_t szBuffer, 173 FX_FILESIZE pos) { 174 if (!m_hFile) { 175 return 0; 176 } 177 if (SetPosition(pos) == (FX_FILESIZE)-1) { 178 return 0; 179 } 180 return Write(pBuffer, szBuffer); 181 } 182 183 bool CFX_FileAccess_Windows::Flush() { 184 if (!m_hFile) 185 return false; 186 187 return !!::FlushFileBuffers(m_hFile); 188 } 189 190 bool CFX_FileAccess_Windows::Truncate(FX_FILESIZE szFile) { 191 if (SetPosition(szFile) == (FX_FILESIZE)-1) 192 return false; 193 194 return !!::SetEndOfFile(m_hFile); 195 } 196 #endif 197