• 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_stream.h"
12 #include "core/fxcrt/fx_string.h"
13 #include "third_party/base/ptr_util.h"
14 
15 namespace {
16 
GetFileMode(uint32_t dwMode,uint32_t & dwAccess,uint32_t & dwShare,uint32_t & dwCreation)17 void GetFileMode(uint32_t dwMode,
18                  uint32_t& dwAccess,
19                  uint32_t& dwShare,
20                  uint32_t& dwCreation) {
21   dwAccess = GENERIC_READ;
22   dwShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
23   if (!(dwMode & FX_FILEMODE_ReadOnly)) {
24     dwAccess |= GENERIC_WRITE;
25     dwCreation = (dwMode & FX_FILEMODE_Truncate) ? CREATE_ALWAYS : OPEN_ALWAYS;
26   } else {
27     dwCreation = OPEN_EXISTING;
28   }
29 }
30 
31 }  // namespace
32 
33 // static
Create()34 std::unique_ptr<FileAccessIface> FileAccessIface::Create() {
35   return pdfium::MakeUnique<CFX_FileAccess_Windows>();
36 }
37 
CFX_FileAccess_Windows()38 CFX_FileAccess_Windows::CFX_FileAccess_Windows() : m_hFile(nullptr) {}
39 
~CFX_FileAccess_Windows()40 CFX_FileAccess_Windows::~CFX_FileAccess_Windows() {
41   Close();
42 }
43 
Open(ByteStringView fileName,uint32_t dwMode)44 bool CFX_FileAccess_Windows::Open(ByteStringView fileName, uint32_t dwMode) {
45   if (m_hFile)
46     return false;
47 
48   uint32_t dwAccess, dwShare, dwCreation;
49   GetFileMode(dwMode, dwAccess, dwShare, dwCreation);
50   m_hFile = ::CreateFileA(fileName.unterminated_c_str(), dwAccess, dwShare,
51                           nullptr, dwCreation, FILE_ATTRIBUTE_NORMAL, nullptr);
52   if (m_hFile == INVALID_HANDLE_VALUE)
53     m_hFile = nullptr;
54 
55   return !!m_hFile;
56 }
57 
Open(WideStringView fileName,uint32_t dwMode)58 bool CFX_FileAccess_Windows::Open(WideStringView fileName, 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 =
65       ::CreateFileW((LPCWSTR)fileName.unterminated_c_str(), dwAccess, dwShare,
66                     nullptr, dwCreation, FILE_ATTRIBUTE_NORMAL, nullptr);
67   if (m_hFile == INVALID_HANDLE_VALUE)
68     m_hFile = nullptr;
69 
70   return !!m_hFile;
71 }
72 
Close()73 void CFX_FileAccess_Windows::Close() {
74   if (!m_hFile)
75     return;
76 
77   ::CloseHandle(m_hFile);
78   m_hFile = nullptr;
79 }
80 
GetSize() const81 FX_FILESIZE CFX_FileAccess_Windows::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 
GetPosition() const92 FX_FILESIZE CFX_FileAccess_Windows::GetPosition() const {
93   if (!m_hFile)
94     return (FX_FILESIZE)-1;
95 
96   LARGE_INTEGER dist = {};
97   LARGE_INTEGER newPos = {};
98   if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_CURRENT))
99     return (FX_FILESIZE)-1;
100 
101   return (FX_FILESIZE)newPos.QuadPart;
102 }
103 
SetPosition(FX_FILESIZE pos)104 FX_FILESIZE CFX_FileAccess_Windows::SetPosition(FX_FILESIZE pos) {
105   if (!m_hFile)
106     return (FX_FILESIZE)-1;
107 
108   LARGE_INTEGER dist;
109   dist.QuadPart = pos;
110   LARGE_INTEGER newPos = {};
111   if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_BEGIN))
112     return (FX_FILESIZE)-1;
113 
114   return (FX_FILESIZE)newPos.QuadPart;
115 }
116 
Read(void * pBuffer,size_t szBuffer)117 size_t CFX_FileAccess_Windows::Read(void* pBuffer, size_t szBuffer) {
118   if (!m_hFile)
119     return 0;
120 
121   size_t szRead = 0;
122   if (!::ReadFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szRead,
123                   nullptr)) {
124     return 0;
125   }
126   return szRead;
127 }
128 
Write(const void * pBuffer,size_t szBuffer)129 size_t CFX_FileAccess_Windows::Write(const void* pBuffer, size_t szBuffer) {
130   if (!m_hFile)
131     return 0;
132 
133   size_t szWrite = 0;
134   if (!::WriteFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szWrite,
135                    nullptr)) {
136     return 0;
137   }
138   return szWrite;
139 }
140 
ReadPos(void * pBuffer,size_t szBuffer,FX_FILESIZE pos)141 size_t CFX_FileAccess_Windows::ReadPos(void* pBuffer,
142                                        size_t szBuffer,
143                                        FX_FILESIZE pos) {
144   if (!m_hFile)
145     return 0;
146 
147   if (pos >= GetSize())
148     return 0;
149 
150   if (SetPosition(pos) == (FX_FILESIZE)-1)
151     return 0;
152 
153   return Read(pBuffer, szBuffer);
154 }
155 
WritePos(const void * pBuffer,size_t szBuffer,FX_FILESIZE pos)156 size_t CFX_FileAccess_Windows::WritePos(const void* pBuffer,
157                                         size_t szBuffer,
158                                         FX_FILESIZE pos) {
159   if (!m_hFile) {
160     return 0;
161   }
162   if (SetPosition(pos) == (FX_FILESIZE)-1) {
163     return 0;
164   }
165   return Write(pBuffer, szBuffer);
166 }
167 
Flush()168 bool CFX_FileAccess_Windows::Flush() {
169   if (!m_hFile)
170     return false;
171 
172   return !!::FlushFileBuffers(m_hFile);
173 }
174 
Truncate(FX_FILESIZE szFile)175 bool CFX_FileAccess_Windows::Truncate(FX_FILESIZE szFile) {
176   if (SetPosition(szFile) == (FX_FILESIZE)-1)
177     return false;
178 
179   return !!::SetEndOfFile(m_hFile);
180 }
181