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