• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
Create()14 IFXCRT_FileAccess* IFXCRT_FileAccess::Create() {
15   return new CFXCRT_FileAccess_Win64;
16 }
17 
FXCRT_Windows_GetFileMode(uint32_t dwMode,uint32_t & dwAccess,uint32_t & dwShare,uint32_t & dwCreation)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 
CFXCRT_FileAccess_Win64()44 CFXCRT_FileAccess_Win64::CFXCRT_FileAccess_Win64() : m_hFile(nullptr) {}
45 
~CFXCRT_FileAccess_Win64()46 CFXCRT_FileAccess_Win64::~CFXCRT_FileAccess_Win64() {
47   Close();
48 }
49 
Open(const CFX_ByteStringC & fileName,uint32_t dwMode)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 
Open(const CFX_WideStringC & fileName,uint32_t dwMode)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 
Close()80 void CFXCRT_FileAccess_Win64::Close() {
81   if (!m_hFile)
82     return;
83 
84   ::CloseHandle(m_hFile);
85   m_hFile = nullptr;
86 }
87 
GetSize() const88 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 
GetPosition() const99 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 
SetPosition(FX_FILESIZE pos)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 
Read(void * pBuffer,size_t szBuffer)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 
Write(const void * pBuffer,size_t szBuffer)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 
ReadPos(void * pBuffer,size_t szBuffer,FX_FILESIZE pos)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 
WritePos(const void * pBuffer,size_t szBuffer,FX_FILESIZE pos)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 
Flush()175 bool CFXCRT_FileAccess_Win64::Flush() {
176   if (!m_hFile)
177     return false;
178 
179   return !!::FlushFileBuffers(m_hFile);
180 }
181 
Truncate(FX_FILESIZE szFile)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