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