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 "fxcrt_windows.h" 8 9 #include "core/include/fxcrt/fx_string.h" 10 11 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 12 IFXCRT_FileAccess* FXCRT_FileAccess_Create() { 13 return new CFXCRT_FileAccess_Win64; 14 } 15 void FXCRT_Windows_GetFileMode(FX_DWORD dwMode, 16 FX_DWORD& dwAccess, 17 FX_DWORD& dwShare, 18 FX_DWORD& dwCreation) { 19 dwAccess = GENERIC_READ; 20 dwShare = FILE_SHARE_READ | FILE_SHARE_WRITE; 21 if (!(dwMode & FX_FILEMODE_ReadOnly)) { 22 dwAccess |= GENERIC_WRITE; 23 dwCreation = (dwMode & FX_FILEMODE_Truncate) ? CREATE_ALWAYS : OPEN_ALWAYS; 24 } else { 25 dwCreation = OPEN_EXISTING; 26 } 27 } 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize); 32 WINBASEAPI BOOL WINAPI SetFilePointerEx(HANDLE hFile, 33 LARGE_INTEGER liDistanceToMove, 34 PLARGE_INTEGER lpNewFilePointer, 35 DWORD dwMoveMethod); 36 #ifdef __cplusplus 37 } 38 #endif 39 CFXCRT_FileAccess_Win64::CFXCRT_FileAccess_Win64() : m_hFile(NULL) {} 40 CFXCRT_FileAccess_Win64::~CFXCRT_FileAccess_Win64() { 41 Close(); 42 } 43 FX_BOOL CFXCRT_FileAccess_Win64::Open(const CFX_ByteStringC& fileName, 44 FX_DWORD dwMode) { 45 if (m_hFile) { 46 return FALSE; 47 } 48 FX_DWORD dwAccess, dwShare, dwCreation; 49 FXCRT_Windows_GetFileMode(dwMode, dwAccess, dwShare, dwCreation); 50 m_hFile = ::CreateFileA(fileName.GetCStr(), dwAccess, dwShare, NULL, 51 dwCreation, FILE_ATTRIBUTE_NORMAL, NULL); 52 if (m_hFile == INVALID_HANDLE_VALUE) { 53 m_hFile = NULL; 54 } 55 return m_hFile != NULL; 56 } 57 FX_BOOL CFXCRT_FileAccess_Win64::Open(const CFX_WideStringC& fileName, 58 FX_DWORD dwMode) { 59 if (m_hFile) { 60 return FALSE; 61 } 62 FX_DWORD dwAccess, dwShare, dwCreation; 63 FXCRT_Windows_GetFileMode(dwMode, dwAccess, dwShare, dwCreation); 64 m_hFile = ::CreateFileW((LPCWSTR)fileName.GetPtr(), dwAccess, dwShare, NULL, 65 dwCreation, FILE_ATTRIBUTE_NORMAL, NULL); 66 if (m_hFile == INVALID_HANDLE_VALUE) { 67 m_hFile = NULL; 68 } 69 return m_hFile != NULL; 70 } 71 void CFXCRT_FileAccess_Win64::Close() { 72 if (!m_hFile) { 73 return; 74 } 75 ::CloseHandle(m_hFile); 76 m_hFile = NULL; 77 } 78 void CFXCRT_FileAccess_Win64::Release() { 79 delete this; 80 } 81 FX_FILESIZE CFXCRT_FileAccess_Win64::GetSize() const { 82 if (!m_hFile) { 83 return 0; 84 } 85 LARGE_INTEGER size = {}; 86 if (!::GetFileSizeEx(m_hFile, &size)) { 87 return 0; 88 } 89 return (FX_FILESIZE)size.QuadPart; 90 } 91 FX_FILESIZE CFXCRT_FileAccess_Win64::GetPosition() const { 92 if (!m_hFile) { 93 return (FX_FILESIZE)-1; 94 } 95 LARGE_INTEGER dist = {}; 96 LARGE_INTEGER newPos = {}; 97 if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_CURRENT)) { 98 return (FX_FILESIZE)-1; 99 } 100 return (FX_FILESIZE)newPos.QuadPart; 101 } 102 FX_FILESIZE CFXCRT_FileAccess_Win64::SetPosition(FX_FILESIZE pos) { 103 if (!m_hFile) { 104 return (FX_FILESIZE)-1; 105 } 106 LARGE_INTEGER dist; 107 dist.QuadPart = pos; 108 LARGE_INTEGER newPos = {}; 109 if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_BEGIN)) { 110 return (FX_FILESIZE)-1; 111 } 112 return (FX_FILESIZE)newPos.QuadPart; 113 } 114 size_t CFXCRT_FileAccess_Win64::Read(void* pBuffer, size_t szBuffer) { 115 if (!m_hFile) { 116 return 0; 117 } 118 size_t szRead = 0; 119 if (!::ReadFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szRead, NULL)) { 120 return 0; 121 } 122 return szRead; 123 } 124 size_t CFXCRT_FileAccess_Win64::Write(const void* pBuffer, size_t szBuffer) { 125 if (!m_hFile) { 126 return 0; 127 } 128 size_t szWrite = 0; 129 if (!::WriteFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szWrite, 130 NULL)) { 131 return 0; 132 } 133 return szWrite; 134 } 135 size_t CFXCRT_FileAccess_Win64::ReadPos(void* pBuffer, 136 size_t szBuffer, 137 FX_FILESIZE pos) { 138 if (!m_hFile) { 139 return 0; 140 } 141 if (pos >= GetSize()) { 142 return 0; 143 } 144 if (SetPosition(pos) == (FX_FILESIZE)-1) { 145 return 0; 146 } 147 return Read(pBuffer, szBuffer); 148 } 149 size_t CFXCRT_FileAccess_Win64::WritePos(const void* pBuffer, 150 size_t szBuffer, 151 FX_FILESIZE pos) { 152 if (!m_hFile) { 153 return 0; 154 } 155 if (SetPosition(pos) == (FX_FILESIZE)-1) { 156 return 0; 157 } 158 return Write(pBuffer, szBuffer); 159 } 160 FX_BOOL CFXCRT_FileAccess_Win64::Flush() { 161 if (!m_hFile) { 162 return FALSE; 163 } 164 return ::FlushFileBuffers(m_hFile); 165 } 166 FX_BOOL CFXCRT_FileAccess_Win64::Truncate(FX_FILESIZE szFile) { 167 if (SetPosition(szFile) == (FX_FILESIZE)-1) { 168 return FALSE; 169 } 170 return ::SetEndOfFile(m_hFile); 171 } 172 #endif 173