• 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/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 
GetFileMode(uint32_t dwMode,uint32_t & dwAccess,uint32_t & dwShare,uint32_t & dwCreation)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
Create()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 
CFX_FileAccess_Windows()51 CFX_FileAccess_Windows::CFX_FileAccess_Windows() : m_hFile(nullptr) {}
52 
~CFX_FileAccess_Windows()53 CFX_FileAccess_Windows::~CFX_FileAccess_Windows() {
54   Close();
55 }
56 
Open(const ByteStringView & fileName,uint32_t dwMode)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 
Open(const WideStringView & fileName,uint32_t dwMode)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 
Close()88 void CFX_FileAccess_Windows::Close() {
89   if (!m_hFile)
90     return;
91 
92   ::CloseHandle(m_hFile);
93   m_hFile = nullptr;
94 }
95 
GetSize() const96 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 
GetPosition() const107 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 
SetPosition(FX_FILESIZE pos)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 
Read(void * pBuffer,size_t szBuffer)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 
Write(const void * pBuffer,size_t szBuffer)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 
ReadPos(void * pBuffer,size_t szBuffer,FX_FILESIZE pos)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 
WritePos(const void * pBuffer,size_t szBuffer,FX_FILESIZE pos)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 
Flush()183 bool CFX_FileAccess_Windows::Flush() {
184   if (!m_hFile)
185     return false;
186 
187   return !!::FlushFileBuffers(m_hFile);
188 }
189 
Truncate(FX_FILESIZE szFile)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