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