Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java
41139 views
1
/*
2
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.nio.fs;
27
28
import java.nio.file.*;
29
import static java.nio.file.StandardOpenOption.*;
30
import java.nio.ByteBuffer;
31
import java.nio.channels.FileChannel;
32
import java.io.IOException;
33
import java.util.*;
34
import jdk.internal.misc.Unsafe;
35
36
import static sun.nio.fs.WindowsNativeDispatcher.*;
37
import static sun.nio.fs.WindowsConstants.*;
38
39
/**
40
* Windows emulation of NamedAttributeView using Alternative Data Streams
41
*/
42
43
class WindowsUserDefinedFileAttributeView
44
extends AbstractUserDefinedFileAttributeView
45
{
46
private static final Unsafe unsafe = Unsafe.getUnsafe();
47
48
// syntax to address named streams
49
private String join(String file, String name) {
50
if (name == null)
51
throw new NullPointerException("'name' is null");
52
return file + ":" + name;
53
}
54
private String join(WindowsPath file, String name) throws WindowsException {
55
return join(file.getPathForWin32Calls(), name);
56
}
57
58
private final WindowsPath file;
59
private final boolean followLinks;
60
61
WindowsUserDefinedFileAttributeView(WindowsPath file, boolean followLinks) {
62
this.file = file;
63
this.followLinks = followLinks;
64
}
65
66
// enumerates the file streams using FindFirstStream/FindNextStream APIs.
67
private List<String> listUsingStreamEnumeration() throws IOException {
68
List<String> list = new ArrayList<>();
69
try {
70
FirstStream first = FindFirstStream(file.getPathForWin32Calls());
71
if (first != null) {
72
long handle = first.handle();
73
try {
74
// first stream is always ::$DATA for files
75
String name = first.name();
76
if (!name.equals("::$DATA")) {
77
String[] segs = name.split(":");
78
list.add(segs[1]);
79
}
80
while ((name = FindNextStream(handle)) != null) {
81
String[] segs = name.split(":");
82
list.add(segs[1]);
83
}
84
} finally {
85
FindClose(handle);
86
}
87
}
88
} catch (WindowsException x) {
89
x.rethrowAsIOException(file);
90
}
91
return Collections.unmodifiableList(list);
92
}
93
94
@SuppressWarnings("removal")
95
@Override
96
public List<String> list() throws IOException {
97
if (System.getSecurityManager() != null)
98
checkAccess(file.getPathForPermissionCheck(), true, false);
99
return listUsingStreamEnumeration();
100
}
101
102
@SuppressWarnings("removal")
103
@Override
104
public int size(String name) throws IOException {
105
if (System.getSecurityManager() != null)
106
checkAccess(file.getPathForPermissionCheck(), true, false);
107
108
// wrap with channel
109
FileChannel fc = null;
110
try {
111
Set<OpenOption> opts = new HashSet<>();
112
opts.add(READ);
113
if (!followLinks)
114
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
115
fc = WindowsChannelFactory
116
.newFileChannel(join(file, name), null, opts, 0L);
117
} catch (WindowsException x) {
118
x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name));
119
}
120
try {
121
long size = fc.size();
122
if (size > Integer.MAX_VALUE)
123
throw new ArithmeticException("Stream too large");
124
return (int)size;
125
} finally {
126
fc.close();
127
}
128
}
129
130
@SuppressWarnings("removal")
131
@Override
132
public int read(String name, ByteBuffer dst) throws IOException {
133
if (System.getSecurityManager() != null)
134
checkAccess(file.getPathForPermissionCheck(), true, false);
135
136
// wrap with channel
137
FileChannel fc = null;
138
try {
139
Set<OpenOption> opts = new HashSet<>();
140
opts.add(READ);
141
if (!followLinks)
142
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
143
fc = WindowsChannelFactory
144
.newFileChannel(join(file, name), null, opts, 0L);
145
} catch (WindowsException x) {
146
x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name));
147
}
148
149
// read to EOF (nothing we can do if I/O error occurs)
150
try {
151
if (fc.size() > dst.remaining())
152
throw new IOException("Stream too large");
153
int total = 0;
154
while (dst.hasRemaining()) {
155
int n = fc.read(dst);
156
if (n < 0)
157
break;
158
total += n;
159
}
160
return total;
161
} finally {
162
fc.close();
163
}
164
}
165
166
@SuppressWarnings("removal")
167
@Override
168
public int write(String name, ByteBuffer src) throws IOException {
169
if (System.getSecurityManager() != null)
170
checkAccess(file.getPathForPermissionCheck(), false, true);
171
172
/**
173
* Creating a named stream will cause the unnamed stream to be created
174
* if it doesn't already exist. To avoid this we open the unnamed stream
175
* for reading and hope it isn't deleted/moved while we create or
176
* replace the named stream. Opening the file without sharing options
177
* may cause sharing violations with other programs that are accessing
178
* the unnamed stream.
179
*/
180
long handle = -1L;
181
try {
182
int flags = FILE_FLAG_BACKUP_SEMANTICS;
183
if (!followLinks)
184
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
185
186
handle = CreateFile(file.getPathForWin32Calls(),
187
GENERIC_READ,
188
(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
189
OPEN_EXISTING,
190
flags);
191
} catch (WindowsException x) {
192
x.rethrowAsIOException(file);
193
}
194
try {
195
Set<OpenOption> opts = new HashSet<>();
196
if (!followLinks)
197
opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT);
198
opts.add(CREATE);
199
opts.add(WRITE);
200
opts.add(StandardOpenOption.TRUNCATE_EXISTING);
201
FileChannel named = null;
202
try {
203
named = WindowsChannelFactory
204
.newFileChannel(join(file, name), null, opts, 0L);
205
} catch (WindowsException x) {
206
x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name));
207
}
208
// write value (nothing we can do if I/O error occurs)
209
try {
210
int rem = src.remaining();
211
while (src.hasRemaining()) {
212
named.write(src);
213
}
214
return rem;
215
} finally {
216
named.close();
217
}
218
} finally {
219
CloseHandle(handle);
220
}
221
}
222
223
@SuppressWarnings("removal")
224
@Override
225
public void delete(String name) throws IOException {
226
if (System.getSecurityManager() != null)
227
checkAccess(file.getPathForPermissionCheck(), false, true);
228
229
String path = WindowsLinkSupport.getFinalPath(file, followLinks);
230
String toDelete = join(path, name);
231
try {
232
DeleteFile(toDelete);
233
} catch (WindowsException x) {
234
x.rethrowAsIOException(toDelete);
235
}
236
}
237
}
238
239