xref: /aosp_15_r20/external/pdfium/core/fxcrt/cfx_fileaccess_windows.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2014 The PDFium Authors
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 
14 // static
Create()15 std::unique_ptr<FileAccessIface> FileAccessIface::Create() {
16   return std::make_unique<CFX_FileAccess_Windows>();
17 }
18 
19 CFX_FileAccess_Windows::CFX_FileAccess_Windows() = default;
20 
~CFX_FileAccess_Windows()21 CFX_FileAccess_Windows::~CFX_FileAccess_Windows() {
22   Close();
23 }
24 
Open(ByteStringView fileName)25 bool CFX_FileAccess_Windows::Open(ByteStringView fileName) {
26   if (m_hFile)
27     return false;
28 
29   WideString wname = FX_UTF8Decode(fileName);
30   m_hFile = ::CreateFileW(wname.c_str(), GENERIC_READ,
31                           FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
32                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
33   if (m_hFile == INVALID_HANDLE_VALUE)
34     m_hFile = nullptr;
35 
36   return !!m_hFile;
37 }
38 
Close()39 void CFX_FileAccess_Windows::Close() {
40   if (!m_hFile)
41     return;
42 
43   ::CloseHandle(m_hFile);
44   m_hFile = nullptr;
45 }
46 
GetSize() const47 FX_FILESIZE CFX_FileAccess_Windows::GetSize() const {
48   if (!m_hFile)
49     return 0;
50 
51   LARGE_INTEGER size = {};
52   if (!::GetFileSizeEx(m_hFile, &size))
53     return 0;
54 
55   return (FX_FILESIZE)size.QuadPart;
56 }
57 
GetPosition() const58 FX_FILESIZE CFX_FileAccess_Windows::GetPosition() const {
59   if (!m_hFile)
60     return (FX_FILESIZE)-1;
61 
62   LARGE_INTEGER dist = {};
63   LARGE_INTEGER newPos = {};
64   if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_CURRENT))
65     return (FX_FILESIZE)-1;
66 
67   return (FX_FILESIZE)newPos.QuadPart;
68 }
69 
SetPosition(FX_FILESIZE pos)70 FX_FILESIZE CFX_FileAccess_Windows::SetPosition(FX_FILESIZE pos) {
71   if (!m_hFile)
72     return (FX_FILESIZE)-1;
73 
74   LARGE_INTEGER dist;
75   dist.QuadPart = pos;
76   LARGE_INTEGER newPos = {};
77   if (!::SetFilePointerEx(m_hFile, dist, &newPos, FILE_BEGIN))
78     return (FX_FILESIZE)-1;
79 
80   return (FX_FILESIZE)newPos.QuadPart;
81 }
82 
Read(void * pBuffer,size_t szBuffer)83 size_t CFX_FileAccess_Windows::Read(void* pBuffer, size_t szBuffer) {
84   if (!m_hFile)
85     return 0;
86 
87   size_t szRead = 0;
88   if (!::ReadFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szRead,
89                   nullptr)) {
90     return 0;
91   }
92   return szRead;
93 }
94 
Write(const void * pBuffer,size_t szBuffer)95 size_t CFX_FileAccess_Windows::Write(const void* pBuffer, size_t szBuffer) {
96   if (!m_hFile)
97     return 0;
98 
99   size_t szWrite = 0;
100   if (!::WriteFile(m_hFile, pBuffer, (DWORD)szBuffer, (LPDWORD)&szWrite,
101                    nullptr)) {
102     return 0;
103   }
104   return szWrite;
105 }
106 
ReadPos(void * pBuffer,size_t szBuffer,FX_FILESIZE pos)107 size_t CFX_FileAccess_Windows::ReadPos(void* pBuffer,
108                                        size_t szBuffer,
109                                        FX_FILESIZE pos) {
110   if (!m_hFile)
111     return 0;
112 
113   if (pos >= GetSize())
114     return 0;
115 
116   if (SetPosition(pos) == (FX_FILESIZE)-1)
117     return 0;
118 
119   return Read(pBuffer, szBuffer);
120 }
121 
WritePos(const void * pBuffer,size_t szBuffer,FX_FILESIZE pos)122 size_t CFX_FileAccess_Windows::WritePos(const void* pBuffer,
123                                         size_t szBuffer,
124                                         FX_FILESIZE pos) {
125   if (!m_hFile) {
126     return 0;
127   }
128   if (SetPosition(pos) == (FX_FILESIZE)-1) {
129     return 0;
130   }
131   return Write(pBuffer, szBuffer);
132 }
133 
Flush()134 bool CFX_FileAccess_Windows::Flush() {
135   if (!m_hFile)
136     return false;
137 
138   return !!::FlushFileBuffers(m_hFile);
139 }
140 
Truncate(FX_FILESIZE szFile)141 bool CFX_FileAccess_Windows::Truncate(FX_FILESIZE szFile) {
142   if (SetPosition(szFile) == (FX_FILESIZE)-1)
143     return false;
144 
145   return !!::SetEndOfFile(m_hFile);
146 }
147