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_
FXCRT_FileAccess_Create()12 IFXCRT_FileAccess* FXCRT_FileAccess_Create() {
13 return new CFXCRT_FileAccess_Win64;
14 }
FXCRT_Windows_GetFileMode(FX_DWORD dwMode,FX_DWORD & dwAccess,FX_DWORD & dwShare,FX_DWORD & dwCreation)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
CFXCRT_FileAccess_Win64()39 CFXCRT_FileAccess_Win64::CFXCRT_FileAccess_Win64() : m_hFile(NULL) {}
~CFXCRT_FileAccess_Win64()40 CFXCRT_FileAccess_Win64::~CFXCRT_FileAccess_Win64() {
41 Close();
42 }
Open(const CFX_ByteStringC & fileName,FX_DWORD dwMode)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 }
Open(const CFX_WideStringC & fileName,FX_DWORD dwMode)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 }
Close()71 void CFXCRT_FileAccess_Win64::Close() {
72 if (!m_hFile) {
73 return;
74 }
75 ::CloseHandle(m_hFile);
76 m_hFile = NULL;
77 }
Release()78 void CFXCRT_FileAccess_Win64::Release() {
79 delete this;
80 }
GetSize() const81 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 }
GetPosition() const91 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 }
SetPosition(FX_FILESIZE pos)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 }
Read(void * pBuffer,size_t szBuffer)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 }
Write(const void * pBuffer,size_t szBuffer)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 }
ReadPos(void * pBuffer,size_t szBuffer,FX_FILESIZE pos)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 }
WritePos(const void * pBuffer,size_t szBuffer,FX_FILESIZE pos)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 }
Flush()160 FX_BOOL CFXCRT_FileAccess_Win64::Flush() {
161 if (!m_hFile) {
162 return FALSE;
163 }
164 return ::FlushFileBuffers(m_hFile);
165 }
Truncate(FX_FILESIZE szFile)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