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/WindowsFileAttributes.java
41139 views
1
/*
2
* Copyright (c) 2008, 2019, 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.attribute.*;
29
import java.util.concurrent.TimeUnit;
30
import jdk.internal.misc.Unsafe;
31
import sun.security.action.GetPropertyAction;
32
33
import static sun.nio.fs.WindowsNativeDispatcher.*;
34
import static sun.nio.fs.WindowsConstants.*;
35
36
/**
37
* Windows implementation of DosFileAttributes/BasicFileAttributes
38
*/
39
40
class WindowsFileAttributes
41
implements DosFileAttributes
42
{
43
private static final Unsafe unsafe = Unsafe.getUnsafe();
44
45
/*
46
* typedef struct _BY_HANDLE_FILE_INFORMATION {
47
* DWORD dwFileAttributes;
48
* FILETIME ftCreationTime;
49
* FILETIME ftLastAccessTime;
50
* FILETIME ftLastWriteTime;
51
* DWORD dwVolumeSerialNumber;
52
* DWORD nFileSizeHigh;
53
* DWORD nFileSizeLow;
54
* DWORD nNumberOfLinks;
55
* DWORD nFileIndexHigh;
56
* DWORD nFileIndexLow;
57
* } BY_HANDLE_FILE_INFORMATION;
58
*/
59
private static final short SIZEOF_FILE_INFORMATION = 52;
60
private static final short OFFSETOF_FILE_INFORMATION_ATTRIBUTES = 0;
61
private static final short OFFSETOF_FILE_INFORMATION_CREATETIME = 4;
62
private static final short OFFSETOF_FILE_INFORMATION_LASTACCESSTIME = 12;
63
private static final short OFFSETOF_FILE_INFORMATION_LASTWRITETIME = 20;
64
private static final short OFFSETOF_FILE_INFORMATION_VOLSERIALNUM = 28;
65
private static final short OFFSETOF_FILE_INFORMATION_SIZEHIGH = 32;
66
private static final short OFFSETOF_FILE_INFORMATION_SIZELOW = 36;
67
private static final short OFFSETOF_FILE_INFORMATION_INDEXHIGH = 44;
68
private static final short OFFSETOF_FILE_INFORMATION_INDEXLOW = 48;
69
70
/*
71
* typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
72
* DWORD dwFileAttributes;
73
* FILETIME ftCreationTime;
74
* FILETIME ftLastAccessTime;
75
* FILETIME ftLastWriteTime;
76
* DWORD nFileSizeHigh;
77
* DWORD nFileSizeLow;
78
* } WIN32_FILE_ATTRIBUTE_DATA;
79
*/
80
private static final short SIZEOF_FILE_ATTRIBUTE_DATA = 36;
81
private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES = 0;
82
private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_CREATETIME = 4;
83
private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_LASTACCESSTIME = 12;
84
private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_LASTWRITETIME = 20;
85
private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_SIZEHIGH = 28;
86
private static final short OFFSETOF_FILE_ATTRIBUTE_DATA_SIZELOW = 32;
87
88
/**
89
* typedef struct _WIN32_FIND_DATA {
90
* DWORD dwFileAttributes;
91
* FILETIME ftCreationTime;
92
* FILETIME ftLastAccessTime;
93
* FILETIME ftLastWriteTime;
94
* DWORD nFileSizeHigh;
95
* DWORD nFileSizeLow;
96
* DWORD dwReserved0;
97
* DWORD dwReserved1;
98
* TCHAR cFileName[MAX_PATH];
99
* TCHAR cAlternateFileName[14];
100
* } WIN32_FIND_DATA;
101
*/
102
private static final short SIZEOF_FIND_DATA = 592;
103
private static final short OFFSETOF_FIND_DATA_ATTRIBUTES = 0;
104
private static final short OFFSETOF_FIND_DATA_CREATETIME = 4;
105
private static final short OFFSETOF_FIND_DATA_LASTACCESSTIME = 12;
106
private static final short OFFSETOF_FIND_DATA_LASTWRITETIME = 20;
107
private static final short OFFSETOF_FIND_DATA_SIZEHIGH = 28;
108
private static final short OFFSETOF_FIND_DATA_SIZELOW = 32;
109
private static final short OFFSETOF_FIND_DATA_RESERVED0 = 36;
110
111
// used to adjust values between Windows and java epochs
112
private static final long WINDOWS_EPOCH_IN_MICROS = -11644473600000000L;
113
private static final long WINDOWS_EPOCH_IN_100NS = -116444736000000000L;
114
115
// indicates if accurate metadata is required (interesting on NTFS only)
116
private static final boolean ensureAccurateMetadata;
117
static {
118
String propValue = GetPropertyAction.privilegedGetProperty(
119
"sun.nio.fs.ensureAccurateMetadata", "false");
120
ensureAccurateMetadata = propValue.isEmpty() ? true : Boolean.parseBoolean(propValue);
121
}
122
123
// attributes
124
private final int fileAttrs;
125
private final long creationTime;
126
private final long lastAccessTime;
127
private final long lastWriteTime;
128
private final long size;
129
private final int reparseTag;
130
131
// additional attributes when using GetFileInformationByHandle
132
private final int volSerialNumber;
133
private final int fileIndexHigh;
134
private final int fileIndexLow;
135
136
/**
137
* Convert 64-bit value representing the number of 100-nanosecond intervals
138
* since January 1, 1601 to a FileTime.
139
*/
140
static FileTime toFileTime(long time) {
141
try {
142
long adjusted = Math.addExact(time, WINDOWS_EPOCH_IN_100NS);
143
long nanos = Math.multiplyExact(adjusted, 100L);
144
return FileTime.from(nanos, TimeUnit.NANOSECONDS);
145
} catch (ArithmeticException e) {
146
long micros = Math.addExact(time/10L, WINDOWS_EPOCH_IN_MICROS);
147
return FileTime.from(micros, TimeUnit.MICROSECONDS);
148
}
149
}
150
151
/**
152
* Convert FileTime to 64-bit value representing the number of
153
* 100-nanosecond intervals since January 1, 1601.
154
*/
155
static long toWindowsTime(FileTime time) {
156
long adjusted = time.to(TimeUnit.NANOSECONDS)/100L;
157
return adjusted - WINDOWS_EPOCH_IN_100NS;
158
}
159
160
/**
161
* Initialize a new instance of this class
162
*/
163
private WindowsFileAttributes(int fileAttrs,
164
long creationTime,
165
long lastAccessTime,
166
long lastWriteTime,
167
long size,
168
int reparseTag,
169
int volSerialNumber,
170
int fileIndexHigh,
171
int fileIndexLow)
172
{
173
this.fileAttrs = fileAttrs;
174
this.creationTime = creationTime;
175
this.lastAccessTime = lastAccessTime;
176
this.lastWriteTime = lastWriteTime;
177
this.size = size;
178
this.reparseTag = reparseTag;
179
this.volSerialNumber = volSerialNumber;
180
this.fileIndexHigh = fileIndexHigh;
181
this.fileIndexLow = fileIndexLow;
182
}
183
184
/**
185
* Create a WindowsFileAttributes from a BY_HANDLE_FILE_INFORMATION structure
186
*/
187
private static WindowsFileAttributes fromFileInformation(long address, int reparseTag) {
188
int fileAttrs = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_ATTRIBUTES);
189
long creationTime = unsafe.getLong(address + OFFSETOF_FILE_INFORMATION_CREATETIME);
190
long lastAccessTime = unsafe.getLong(address + OFFSETOF_FILE_INFORMATION_LASTACCESSTIME);
191
long lastWriteTime = unsafe.getLong(address + OFFSETOF_FILE_INFORMATION_LASTWRITETIME);
192
long size = ((long)(unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_SIZEHIGH)) << 32)
193
+ (unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_SIZELOW) & 0xFFFFFFFFL);
194
int volSerialNumber = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_VOLSERIALNUM);
195
int fileIndexHigh = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_INDEXHIGH);
196
int fileIndexLow = unsafe.getInt(address + OFFSETOF_FILE_INFORMATION_INDEXLOW);
197
return new WindowsFileAttributes(fileAttrs,
198
creationTime,
199
lastAccessTime,
200
lastWriteTime,
201
size,
202
reparseTag,
203
volSerialNumber,
204
fileIndexHigh,
205
fileIndexLow);
206
}
207
208
/**
209
* Create a WindowsFileAttributes from a WIN32_FILE_ATTRIBUTE_DATA structure
210
*/
211
private static WindowsFileAttributes fromFileAttributeData(long address, int reparseTag) {
212
int fileAttrs = unsafe.getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES);
213
long creationTime = unsafe.getLong(address + OFFSETOF_FILE_ATTRIBUTE_DATA_CREATETIME);
214
long lastAccessTime = unsafe.getLong(address + OFFSETOF_FILE_ATTRIBUTE_DATA_LASTACCESSTIME);
215
long lastWriteTime = unsafe.getLong(address + OFFSETOF_FILE_ATTRIBUTE_DATA_LASTWRITETIME);
216
long size = ((long)(unsafe.getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_SIZEHIGH)) << 32)
217
+ (unsafe.getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_SIZELOW) & 0xFFFFFFFFL);
218
return new WindowsFileAttributes(fileAttrs,
219
creationTime,
220
lastAccessTime,
221
lastWriteTime,
222
size,
223
reparseTag,
224
0, // volSerialNumber
225
0, // fileIndexHigh
226
0); // fileIndexLow
227
}
228
229
230
/**
231
* Allocates a native buffer for a WIN32_FIND_DATA structure
232
*/
233
static NativeBuffer getBufferForFindData() {
234
return NativeBuffers.getNativeBuffer(SIZEOF_FIND_DATA);
235
}
236
237
/**
238
* Create a WindowsFileAttributes from a WIN32_FIND_DATA structure
239
*/
240
static WindowsFileAttributes fromFindData(long address) {
241
int fileAttrs = unsafe.getInt(address + OFFSETOF_FIND_DATA_ATTRIBUTES);
242
long creationTime = unsafe.getLong(address + OFFSETOF_FIND_DATA_CREATETIME);
243
long lastAccessTime = unsafe.getLong(address + OFFSETOF_FIND_DATA_LASTACCESSTIME);
244
long lastWriteTime = unsafe.getLong(address + OFFSETOF_FIND_DATA_LASTWRITETIME);
245
long size = ((long)(unsafe.getInt(address + OFFSETOF_FIND_DATA_SIZEHIGH)) << 32)
246
+ (unsafe.getInt(address + OFFSETOF_FIND_DATA_SIZELOW) & 0xFFFFFFFFL);
247
int reparseTag = isReparsePoint(fileAttrs) ?
248
unsafe.getInt(address + OFFSETOF_FIND_DATA_RESERVED0) : 0;
249
return new WindowsFileAttributes(fileAttrs,
250
creationTime,
251
lastAccessTime,
252
lastWriteTime,
253
size,
254
reparseTag,
255
0, // volSerialNumber
256
0, // fileIndexHigh
257
0); // fileIndexLow
258
}
259
260
/**
261
* Reads the attributes of an open file
262
*/
263
static WindowsFileAttributes readAttributes(long handle)
264
throws WindowsException
265
{
266
NativeBuffer buffer = NativeBuffers
267
.getNativeBuffer(SIZEOF_FILE_INFORMATION);
268
try {
269
long address = buffer.address();
270
GetFileInformationByHandle(handle, address);
271
272
// if file is a reparse point then read the tag
273
int reparseTag = 0;
274
int fileAttrs = unsafe
275
.getInt(address + OFFSETOF_FILE_INFORMATION_ATTRIBUTES);
276
if (isReparsePoint(fileAttrs)) {
277
int size = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
278
NativeBuffer reparseBuffer = NativeBuffers.getNativeBuffer(size);
279
try {
280
DeviceIoControlGetReparsePoint(handle, reparseBuffer.address(), size);
281
reparseTag = (int)unsafe.getLong(reparseBuffer.address());
282
} finally {
283
reparseBuffer.release();
284
}
285
}
286
287
return fromFileInformation(address, reparseTag);
288
} finally {
289
buffer.release();
290
}
291
}
292
293
/**
294
* Returns attributes of given file.
295
*/
296
static WindowsFileAttributes get(WindowsPath path, boolean followLinks)
297
throws WindowsException
298
{
299
if (!ensureAccurateMetadata) {
300
WindowsException firstException = null;
301
302
// GetFileAttributesEx is the fastest way to read the attributes
303
NativeBuffer buffer =
304
NativeBuffers.getNativeBuffer(SIZEOF_FILE_ATTRIBUTE_DATA);
305
try {
306
long address = buffer.address();
307
GetFileAttributesEx(path.getPathForWin32Calls(), address);
308
// if reparse point then file may be a sym link; otherwise
309
// just return the attributes
310
int fileAttrs = unsafe
311
.getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES);
312
if (!isReparsePoint(fileAttrs))
313
return fromFileAttributeData(address, 0);
314
} catch (WindowsException x) {
315
if (x.lastError() != ERROR_SHARING_VIOLATION)
316
throw x;
317
firstException = x;
318
} finally {
319
buffer.release();
320
}
321
322
// For sharing violations, fallback to FindFirstFile if the file
323
// is not a root directory.
324
if (firstException != null) {
325
String search = path.getPathForWin32Calls();
326
char last = search.charAt(search.length() -1);
327
if (last == ':' || last == '\\')
328
throw firstException;
329
buffer = getBufferForFindData();
330
try {
331
long handle = FindFirstFile(search, buffer.address());
332
FindClose(handle);
333
WindowsFileAttributes attrs = fromFindData(buffer.address());
334
// FindFirstFile does not follow sym links. Even if
335
// followLinks is false, there isn't sufficient information
336
// in the WIN32_FIND_DATA structure to know if the reparse
337
// point is a sym link.
338
if (attrs.isReparsePoint())
339
throw firstException;
340
return attrs;
341
} catch (WindowsException ignore) {
342
throw firstException;
343
} finally {
344
buffer.release();
345
}
346
}
347
}
348
349
// file is reparse point so need to open file to get attributes
350
long handle = path.openForReadAttributeAccess(followLinks);
351
try {
352
return readAttributes(handle);
353
} finally {
354
CloseHandle(handle);
355
}
356
}
357
358
/**
359
* Returns true if the attributes are of the same file - both files must
360
* be open.
361
*/
362
static boolean isSameFile(WindowsFileAttributes attrs1,
363
WindowsFileAttributes attrs2)
364
{
365
// volume serial number and file index must be the same
366
return (attrs1.volSerialNumber == attrs2.volSerialNumber) &&
367
(attrs1.fileIndexHigh == attrs2.fileIndexHigh) &&
368
(attrs1.fileIndexLow == attrs2.fileIndexLow);
369
}
370
371
/**
372
* Returns true if the attributes are of a file with a reparse point.
373
*/
374
static boolean isReparsePoint(int attributes) {
375
return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
376
}
377
378
// package-private
379
int attributes() {
380
return fileAttrs;
381
}
382
383
int volSerialNumber() {
384
return volSerialNumber;
385
}
386
387
int fileIndexHigh() {
388
return fileIndexHigh;
389
}
390
391
int fileIndexLow() {
392
return fileIndexLow;
393
}
394
395
@Override
396
public long size() {
397
return size;
398
}
399
400
@Override
401
public FileTime lastModifiedTime() {
402
return toFileTime(lastWriteTime);
403
}
404
405
@Override
406
public FileTime lastAccessTime() {
407
return toFileTime(lastAccessTime);
408
}
409
410
@Override
411
public FileTime creationTime() {
412
return toFileTime(creationTime);
413
}
414
415
@Override
416
public Object fileKey() {
417
return null;
418
}
419
420
// package private
421
boolean isReparsePoint() {
422
return isReparsePoint(fileAttrs);
423
}
424
425
boolean isDirectoryLink() {
426
return isSymbolicLink() && ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0);
427
}
428
429
@Override
430
public boolean isSymbolicLink() {
431
return reparseTag == IO_REPARSE_TAG_SYMLINK;
432
}
433
434
boolean isUnixDomainSocket() {
435
return reparseTag == IO_REPARSE_TAG_AF_UNIX;
436
}
437
438
@Override
439
public boolean isDirectory() {
440
// ignore FILE_ATTRIBUTE_DIRECTORY attribute if file is a sym link
441
if (isSymbolicLink())
442
return false;
443
return ((fileAttrs & FILE_ATTRIBUTE_DIRECTORY) != 0);
444
}
445
446
@Override
447
public boolean isOther() {
448
if (isSymbolicLink())
449
return false;
450
// return true if device or reparse point
451
return ((fileAttrs & (FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0);
452
}
453
454
@Override
455
public boolean isRegularFile() {
456
return !isSymbolicLink() && !isDirectory() && !isOther();
457
}
458
459
@Override
460
public boolean isReadOnly() {
461
return (fileAttrs & FILE_ATTRIBUTE_READONLY) != 0;
462
}
463
464
@Override
465
public boolean isHidden() {
466
return (fileAttrs & FILE_ATTRIBUTE_HIDDEN) != 0;
467
}
468
469
@Override
470
public boolean isArchive() {
471
return (fileAttrs & FILE_ATTRIBUTE_ARCHIVE) != 0;
472
}
473
474
@Override
475
public boolean isSystem() {
476
return (fileAttrs & FILE_ATTRIBUTE_SYSTEM) != 0;
477
}
478
}
479
480