mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-25 10:49:41 +01:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f950ff463c | ||
|
|
cf2f09827c | ||
|
|
152a4e886d | ||
|
|
ef6db5cad0 | ||
|
|
6d1c3f06c4 | ||
|
|
7c2d7541ba | ||
|
|
4d01bcc46e | ||
|
|
7d915be754 | ||
|
|
f2bcb756f8 | ||
|
|
a38b7a22fe | ||
|
|
8e58801c9a | ||
|
|
7864d59d6f | ||
|
|
aad640dcc9 | ||
|
|
37901295e1 | ||
|
|
ad1595b5c2 | ||
|
|
f5c5388fb5 | ||
|
|
0bf13985d5 | ||
|
|
2f772fd1a2 | ||
|
|
accef6f21e |
@@ -254,6 +254,7 @@ void setOSNameAndVersion(java_props_t *sprops) {
|
||||
// Hardcode os_name, and fill in os_version
|
||||
sprops->os_name = strdup("Mac OS X");
|
||||
|
||||
NSString *nsVerStr = NULL;
|
||||
char* osVersionCStr = NULL;
|
||||
// Mac OS 10.9 includes the [NSProcessInfo operatingSystemVersion] function,
|
||||
// but it's not in the 10.9 SDK. So, call it via NSInvocation.
|
||||
@@ -266,7 +267,6 @@ void setOSNameAndVersion(java_props_t *sprops) {
|
||||
[invoke invokeWithTarget:[NSProcessInfo processInfo]];
|
||||
[invoke getReturnValue:&osVer];
|
||||
|
||||
NSString *nsVerStr;
|
||||
// Copy out the char* if running on version other than 10.16 Mac OS (10.16 == 11.x)
|
||||
// or explicitly requesting version compatibility
|
||||
if (!((long)osVer.majorVersion == 10 && (long)osVer.minorVersion >= 16) ||
|
||||
@@ -278,36 +278,30 @@ void setOSNameAndVersion(java_props_t *sprops) {
|
||||
nsVerStr = [NSString stringWithFormat:@"%ld.%ld.%ld",
|
||||
(long)osVer.majorVersion, (long)osVer.minorVersion, (long)osVer.patchVersion];
|
||||
}
|
||||
// Copy out the char*
|
||||
osVersionCStr = strdup([nsVerStr UTF8String]);
|
||||
} else {
|
||||
// Version 10.16, without explicit env setting of SYSTEM_VERSION_COMPAT
|
||||
// AKA 11.x; compute the version number from the letter in the ProductBuildVersion
|
||||
// AKA 11+ Read the *real* ProductVersion from the hidden link to avoid SYSTEM_VERSION_COMPAT
|
||||
// If not found, fallback below to the SystemVersion.plist
|
||||
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile :
|
||||
@"/System/Library/CoreServices/SystemVersion.plist"];
|
||||
@"/System/Library/CoreServices/.SystemVersionPlatform.plist"];
|
||||
if (version != NULL) {
|
||||
NSString *nsBuildVerStr = [version objectForKey : @"ProductBuildVersion"];
|
||||
if (nsBuildVerStr != NULL && nsBuildVerStr.length >= 3) {
|
||||
int letter = [nsBuildVerStr characterAtIndex:2];
|
||||
if (letter >= 'B' && letter <= 'Z') {
|
||||
int vers = letter - 'A' - 1;
|
||||
asprintf(&osVersionCStr, "11.%d", vers);
|
||||
}
|
||||
}
|
||||
nsVerStr = [version objectForKey : @"ProductVersion"];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback if running on pre-10.9 Mac OS
|
||||
if (osVersionCStr == NULL) {
|
||||
if (nsVerStr == NULL) {
|
||||
NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile :
|
||||
@"/System/Library/CoreServices/SystemVersion.plist"];
|
||||
if (version != NULL) {
|
||||
NSString *nsVerStr = [version objectForKey : @"ProductVersion"];
|
||||
if (nsVerStr != NULL) {
|
||||
osVersionCStr = strdup([nsVerStr UTF8String]);
|
||||
}
|
||||
nsVerStr = [version objectForKey : @"ProductVersion"];
|
||||
}
|
||||
}
|
||||
|
||||
if (nsVerStr != NULL) {
|
||||
// Copy out the char*
|
||||
osVersionCStr = strdup([nsVerStr UTF8String]);
|
||||
}
|
||||
if (osVersionCStr == NULL) {
|
||||
osVersionCStr = strdup("Unknown");
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
package java.nio.file;
|
||||
|
||||
import java.nio.file.attribute.BasicFileAttributeView;
|
||||
import java.nio.file.attribute.BasicWithKeyFileAttributeView;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@@ -216,7 +218,11 @@ class FileTreeWalker implements Closeable {
|
||||
// links then a link target might not exist so get attributes of link
|
||||
BasicFileAttributes attrs;
|
||||
try {
|
||||
attrs = Files.readAttributes(file, BasicFileAttributes.class, linkOptions);
|
||||
BasicFileAttributeView view = Files.getFileAttributeView(file, BasicWithKeyFileAttributeView.class, linkOptions);
|
||||
if (view == null) {
|
||||
view = Files.getFileAttributeView(file, BasicFileAttributeView.class, linkOptions);
|
||||
}
|
||||
attrs = view.readAttributes();
|
||||
} catch (IOException ioe) {
|
||||
if (!followLinks)
|
||||
throw ioe;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.nio.file.attribute;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Similar to {@link BasicFileAttributeView} with a hint to implementors
|
||||
* to retrieve a valid {@link BasicFileAttributes#fileKey()} if possible, even
|
||||
* at a performance cost.
|
||||
*/
|
||||
|
||||
public interface BasicWithKeyFileAttributeView
|
||||
extends BasicFileAttributeView {
|
||||
}
|
||||
@@ -41,16 +41,16 @@ import static sun.nio.fs.WindowsConstants.*;
|
||||
class WindowsDirectoryStream
|
||||
implements DirectoryStream<Path>
|
||||
{
|
||||
private static final int NATIVE_BUFFER_SIZE = 8192;
|
||||
|
||||
private final WindowsPath dir;
|
||||
private final DirectoryStream.Filter<? super Path> filter;
|
||||
|
||||
// handle to directory
|
||||
private final long handle;
|
||||
// first entry in the directory
|
||||
private final String firstName;
|
||||
// Query directory information data structure
|
||||
private final QueryDirectoryInformation queryDirectoryInformation;
|
||||
|
||||
// buffer for WIN32_FIND_DATA structure that receives information about file
|
||||
private final NativeBuffer findDataBuffer;
|
||||
// Buffer used to receive file entries from NtQueryDirectoryInformation calls
|
||||
private final NativeBuffer queryDirectoryInformationBuffer;
|
||||
|
||||
private final Object closeLock = new Object();
|
||||
|
||||
@@ -65,21 +65,15 @@ class WindowsDirectoryStream
|
||||
this.dir = dir;
|
||||
this.filter = filter;
|
||||
|
||||
this.queryDirectoryInformationBuffer = NativeBuffers.getNativeBuffer(NATIVE_BUFFER_SIZE);
|
||||
try {
|
||||
// Need to append * or \* to match entries in directory.
|
||||
// Open the directory for reading and read the first set of entries in the native buffer
|
||||
String search = dir.getPathForWin32Calls();
|
||||
char last = search.charAt(search.length() -1);
|
||||
if (last == ':' || last == '\\') {
|
||||
search += "*";
|
||||
} else {
|
||||
search += "\\*";
|
||||
}
|
||||
|
||||
FirstFile first = FindFirstFile(search);
|
||||
this.handle = first.handle();
|
||||
this.firstName = first.name();
|
||||
this.findDataBuffer = WindowsFileAttributes.getBufferForFindData();
|
||||
this.queryDirectoryInformation = OpenNtQueryDirectoryInformation(search, this.queryDirectoryInformationBuffer);
|
||||
} catch (WindowsException x) {
|
||||
// Release the buffer, as this instance is not fully constructed
|
||||
this.queryDirectoryInformationBuffer.release();
|
||||
|
||||
if (x.lastError() == ERROR_DIRECTORY) {
|
||||
throw new NotDirectoryException(dir.getPathForExceptionMessage());
|
||||
}
|
||||
@@ -99,9 +93,9 @@ class WindowsDirectoryStream
|
||||
return;
|
||||
isOpen = false;
|
||||
}
|
||||
findDataBuffer.release();
|
||||
queryDirectoryInformationBuffer.release();
|
||||
try {
|
||||
FindClose(handle);
|
||||
CloseNtQueryDirectoryInformation(queryDirectoryInformation);
|
||||
} catch (WindowsException x) {
|
||||
x.rethrowAsIOException(dir);
|
||||
}
|
||||
@@ -115,20 +109,20 @@ class WindowsDirectoryStream
|
||||
synchronized (this) {
|
||||
if (iterator != null)
|
||||
throw new IllegalStateException("Iterator already obtained");
|
||||
iterator = new WindowsDirectoryIterator(firstName);
|
||||
iterator = new WindowsDirectoryIterator();
|
||||
return iterator;
|
||||
}
|
||||
}
|
||||
|
||||
private class WindowsDirectoryIterator implements Iterator<Path> {
|
||||
private boolean atEof;
|
||||
private String first;
|
||||
private Path nextEntry;
|
||||
private String prefix;
|
||||
private int nextOffset;
|
||||
|
||||
WindowsDirectoryIterator(String first) {
|
||||
WindowsDirectoryIterator() {
|
||||
atEof = false;
|
||||
this.first = first;
|
||||
nextOffset = 0;
|
||||
if (dir.needsSlashWhenResolving()) {
|
||||
prefix = dir.toString() + "\\";
|
||||
} else {
|
||||
@@ -156,44 +150,40 @@ class WindowsDirectoryStream
|
||||
|
||||
// reads next directory entry
|
||||
private Path readNextEntry() {
|
||||
// handle first element returned by search
|
||||
if (first != null) {
|
||||
nextEntry = isSelfOrParent(first) ? null : acceptEntry(first, null);
|
||||
first = null;
|
||||
if (nextEntry != null)
|
||||
return nextEntry;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
String name = null;
|
||||
String name;
|
||||
WindowsFileAttributes attrs;
|
||||
|
||||
// synchronize on closeLock to prevent close while reading
|
||||
synchronized (closeLock) {
|
||||
try {
|
||||
if (isOpen) {
|
||||
name = FindNextFile(handle, findDataBuffer.address());
|
||||
}
|
||||
} catch (WindowsException x) {
|
||||
IOException ioe = x.asIOException(dir);
|
||||
throw new DirectoryIteratorException(ioe);
|
||||
}
|
||||
|
||||
// NO_MORE_FILES or stream closed
|
||||
if (name == null) {
|
||||
// Fetch next set of entries if we don't have anything available in buffer
|
||||
if (!isOpen) {
|
||||
atEof = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
// ignore link to self and parent directories
|
||||
if (isSelfOrParent(name))
|
||||
continue;
|
||||
if (nextOffset < 0) {
|
||||
try {
|
||||
atEof = !NextNtQueryDirectoryInformation(queryDirectoryInformation, queryDirectoryInformationBuffer);
|
||||
} catch (WindowsException x) {
|
||||
IOException ioe = x.asIOException(dir);
|
||||
throw new DirectoryIteratorException(ioe);
|
||||
}
|
||||
if (atEof) {
|
||||
return null;
|
||||
}
|
||||
nextOffset = 0;
|
||||
}
|
||||
|
||||
// grab the attributes from the WIN32_FIND_DATA structure
|
||||
// (needs to be done while holding closeLock because close
|
||||
// will release the buffer)
|
||||
attrs = WindowsFileAttributes
|
||||
.fromFindData(findDataBuffer.address());
|
||||
long fullDirInformationAddress = queryDirectoryInformationBuffer.address() + nextOffset;
|
||||
int nextEntryOffset = WindowsFileAttributes.getNextOffsetFromFileIdFullDirInformation(fullDirInformationAddress);
|
||||
nextOffset = nextEntryOffset == 0 ? -1 : nextOffset + nextEntryOffset;
|
||||
name = WindowsFileAttributes.getFileNameFromFileIdFullDirInformation(fullDirInformationAddress);
|
||||
if (isSelfOrParent(name)) {
|
||||
// Skip "." and ".."
|
||||
continue;
|
||||
}
|
||||
attrs = WindowsFileAttributes.fromFileIdFullDirInformation(fullDirInformationAddress, queryDirectoryInformation.volSerialNumber());
|
||||
}
|
||||
|
||||
// return entry if accepted by filter
|
||||
|
||||
@@ -150,6 +150,23 @@ class WindowsFileAttributeViews {
|
||||
}
|
||||
}
|
||||
|
||||
private static class BasicWithKey extends Basic {
|
||||
BasicWithKey(WindowsPath file, boolean followLinks) {
|
||||
super(file, followLinks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowsFileAttributes readAttributes() throws IOException {
|
||||
file.checkRead();
|
||||
try {
|
||||
return WindowsFileAttributes.getWithFileKey(file, followLinks);
|
||||
} catch (WindowsException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
return null; // keep compiler happy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class Dos extends Basic implements DosFileAttributeView {
|
||||
private static final String READONLY_NAME = "readonly";
|
||||
private static final String ARCHIVE_NAME = "archive";
|
||||
@@ -289,6 +306,10 @@ class WindowsFileAttributeViews {
|
||||
return new Basic(file, followLinks);
|
||||
}
|
||||
|
||||
static Basic createBasicWithKeyView(WindowsPath file, boolean followLinks) {
|
||||
return new BasicWithKey(file, followLinks);
|
||||
}
|
||||
|
||||
static Dos createDosView(WindowsPath file, boolean followLinks) {
|
||||
return new Dos(file, followLinks);
|
||||
}
|
||||
|
||||
@@ -108,6 +108,34 @@ class WindowsFileAttributes
|
||||
private static final short OFFSETOF_FIND_DATA_SIZELOW = 32;
|
||||
private static final short OFFSETOF_FIND_DATA_RESERVED0 = 36;
|
||||
|
||||
/**
|
||||
* typedef struct _FILE_ID_FULL_DIR_INFORMATION {
|
||||
* ULONG NextEntryOffset; // offset = 0
|
||||
* ULONG FileIndex; // offset = 4
|
||||
* LARGE_INTEGER CreationTime; // offset = 8
|
||||
* LARGE_INTEGER LastAccessTime; // offset = 16
|
||||
* LARGE_INTEGER LastWriteTime; // offset = 24
|
||||
* LARGE_INTEGER ChangeTime; // offset = 32
|
||||
* LARGE_INTEGER EndOfFile; // offset = 40
|
||||
* LARGE_INTEGER AllocationSize; // offset = 48
|
||||
* ULONG FileAttributes; // offset = 56
|
||||
* ULONG FileNameLength; // offset = 60
|
||||
* ULONG EaSize; // offset = 64
|
||||
* LARGE_INTEGER FileId; // offset = 72
|
||||
* WCHAR FileName[1]; // offset = 80
|
||||
* } FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
|
||||
*/
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_NEXT_ENTRY_OFFSET = 0;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_CREATION_TIME = 8;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_LAST_ACCESS_TIME = 16;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_LAST_WRITE_TIME = 24;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_END_OF_FILE = 40;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_FILE_ATTRIBUTES = 56;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_FILENAME_LENGTH = 60;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_EA_SIZE = 64;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_FILE_ID = 72;
|
||||
private static final int OFFSETOF_FULL_DIR_INFO_FILENAME = 80;
|
||||
|
||||
// used to adjust values between Windows and java epoch
|
||||
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
|
||||
|
||||
@@ -132,6 +160,9 @@ class WindowsFileAttributes
|
||||
private final int fileIndexHigh;
|
||||
private final int fileIndexLow;
|
||||
|
||||
// created lazily
|
||||
private volatile WindowsFileKey key;
|
||||
|
||||
/**
|
||||
* Convert 64-bit value representing the number of 100-nanosecond intervals
|
||||
* since January 1, 1601 to a FileTime.
|
||||
@@ -257,6 +288,47 @@ class WindowsFileAttributes
|
||||
0); // fileIndexLow
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WindowsFileAttributes from a FILE_ID_FULL_DIR_INFORMATION structure
|
||||
*/
|
||||
static WindowsFileAttributes fromFileIdFullDirInformation(long address, int volSerialNumber) {
|
||||
int fileAttrs = unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_FILE_ATTRIBUTES);
|
||||
long creationTime = unsafe.getLong(address + OFFSETOF_FULL_DIR_INFO_CREATION_TIME);
|
||||
long lastAccessTime = unsafe.getLong(address + OFFSETOF_FULL_DIR_INFO_LAST_ACCESS_TIME);
|
||||
long lastWriteTime = unsafe.getLong(address + OFFSETOF_FULL_DIR_INFO_LAST_WRITE_TIME);
|
||||
long size = unsafe.getLong(address + OFFSETOF_FULL_DIR_INFO_END_OF_FILE);
|
||||
int reparseTag = isReparsePoint(fileAttrs) ?
|
||||
unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_EA_SIZE) : 0;
|
||||
int fileIndexLow = unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_FILE_ID);
|
||||
int fileIndexHigh = unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_FILE_ID + 4);
|
||||
|
||||
return new WindowsFileAttributes(fileAttrs,
|
||||
creationTime,
|
||||
lastAccessTime,
|
||||
lastWriteTime,
|
||||
size,
|
||||
reparseTag,
|
||||
volSerialNumber,
|
||||
fileIndexHigh, // fileIndexHigh
|
||||
fileIndexLow); // fileIndexLow
|
||||
}
|
||||
|
||||
static int getNextOffsetFromFileIdFullDirInformation(long address) {
|
||||
return unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_NEXT_ENTRY_OFFSET);
|
||||
}
|
||||
|
||||
static String getFileNameFromFileIdFullDirInformation(long address) {
|
||||
// copy the name
|
||||
int nameLengthInBytes = unsafe.getInt(address + OFFSETOF_FULL_DIR_INFO_FILENAME_LENGTH);
|
||||
if ((nameLengthInBytes % 2) != 0) {
|
||||
throw new AssertionError("FileNameLength is not a multiple of 2");
|
||||
}
|
||||
char[] nameAsArray = new char[nameLengthInBytes/2];
|
||||
unsafe.copyMemory(null, address + OFFSETOF_FULL_DIR_INFO_FILENAME, nameAsArray,
|
||||
Unsafe.ARRAY_CHAR_BASE_OFFSET, nameLengthInBytes);
|
||||
return new String(nameAsArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the attributes of an open file
|
||||
*/
|
||||
@@ -347,6 +419,15 @@ class WindowsFileAttributes
|
||||
}
|
||||
|
||||
// file is reparse point so need to open file to get attributes
|
||||
return getWithFileKey(path, followLinks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns attributes of given file.
|
||||
*/
|
||||
static WindowsFileAttributes getWithFileKey(WindowsPath path, boolean followLinks)
|
||||
throws WindowsException
|
||||
{
|
||||
long handle = path.openForReadAttributeAccess(followLinks);
|
||||
try {
|
||||
return readAttributes(handle);
|
||||
@@ -414,7 +495,17 @@ class WindowsFileAttributes
|
||||
|
||||
@Override
|
||||
public Object fileKey() {
|
||||
return null;
|
||||
if (volSerialNumber == 0) {
|
||||
return null;
|
||||
}
|
||||
if (key == null) {
|
||||
synchronized (this) {
|
||||
if (key == null) {
|
||||
key = new WindowsFileKey(volSerialNumber, ((long)fileIndexHigh << 32) + fileIndexLow);
|
||||
}
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// package private
|
||||
|
||||
67
src/java.base/windows/classes/sun/nio/fs/WindowsFileKey.java
Normal file
67
src/java.base/windows/classes/sun/nio/fs/WindowsFileKey.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.nio.fs;
|
||||
|
||||
/**
|
||||
* Container for volume/file id to uniquely identify file.
|
||||
*/
|
||||
|
||||
class WindowsFileKey {
|
||||
private final int volSerialNumber;
|
||||
private final long fileId;
|
||||
|
||||
WindowsFileKey(int volSerialNumber, long fileId) {
|
||||
this.volSerialNumber = volSerialNumber;
|
||||
this.fileId = fileId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int)(volSerialNumber ^ (volSerialNumber >>> 16)) +
|
||||
(int)(fileId ^ (fileId >>> 32));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (!(obj instanceof WindowsFileKey))
|
||||
return false;
|
||||
WindowsFileKey other = (WindowsFileKey)obj;
|
||||
return (this.volSerialNumber == other.volSerialNumber) && (this.fileId == other.fileId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(volId=")
|
||||
.append(Integer.toHexString(volSerialNumber))
|
||||
.append(",fileId=")
|
||||
.append(Long.toHexString(fileId))
|
||||
.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -25,9 +25,17 @@
|
||||
|
||||
package sun.nio.fs;
|
||||
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.*;
|
||||
import java.nio.file.FileStore;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.nio.file.attribute.AclFileAttributeView;
|
||||
import java.nio.file.attribute.BasicFileAttributeView;
|
||||
import java.nio.file.attribute.DosFileAttributeView;
|
||||
import java.nio.file.attribute.FileAttributeView;
|
||||
import java.nio.file.attribute.FileOwnerAttributeView;
|
||||
import java.nio.file.attribute.FileStoreAttributeView;
|
||||
import java.nio.file.attribute.UserDefinedFileAttributeView;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import static sun.nio.fs.WindowsConstants.*;
|
||||
import static sun.nio.fs.WindowsNativeDispatcher.*;
|
||||
@@ -44,6 +52,8 @@ class WindowsFileStore
|
||||
private final int volType;
|
||||
private final String displayName; // returned by toString
|
||||
|
||||
private int hashCode;
|
||||
|
||||
private WindowsFileStore(String root) throws WindowsException {
|
||||
assert root.charAt(root.length()-1) == '\\';
|
||||
this.root = root;
|
||||
@@ -223,12 +233,20 @@ class WindowsFileStore
|
||||
if (!(ob instanceof WindowsFileStore))
|
||||
return false;
|
||||
WindowsFileStore other = (WindowsFileStore)ob;
|
||||
return root.equals(other.root);
|
||||
if (root.equals(other.root))
|
||||
return true;
|
||||
if (volType == DRIVE_FIXED && other.volumeType() == DRIVE_FIXED)
|
||||
return root.equalsIgnoreCase(other.root);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return root.hashCode();
|
||||
if (hashCode == 0) { // Don't care about race
|
||||
hashCode = (volType == DRIVE_FIXED) ?
|
||||
root.toLowerCase(Locale.ROOT).hashCode() : root.hashCode();
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -242,4 +260,4 @@ class WindowsFileStore
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +167,8 @@ class WindowsFileSystemProvider
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
if (view == BasicFileAttributeView.class)
|
||||
return (V) WindowsFileAttributeViews.createBasicView(file, followLinks);
|
||||
if (view == BasicWithKeyFileAttributeView.class)
|
||||
return (V) WindowsFileAttributeViews.createBasicWithKeyView(file, followLinks);
|
||||
if (view == DosFileAttributeView.class)
|
||||
return (V) WindowsFileAttributeViews.createDosView(file, followLinks);
|
||||
if (view == AclFileAttributeView.class)
|
||||
@@ -204,6 +206,8 @@ class WindowsFileSystemProvider
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
if (name.equals("basic"))
|
||||
return WindowsFileAttributeViews.createBasicView(file, followLinks);
|
||||
if (name.equals("basicwithkey"))
|
||||
return WindowsFileAttributeViews.createBasicWithKeyView(file, followLinks);
|
||||
if (name.equals("dos"))
|
||||
return WindowsFileAttributeViews.createDosView(file, followLinks);
|
||||
if (name.equals("acl"))
|
||||
|
||||
@@ -277,6 +277,38 @@ class WindowsNativeDispatcher {
|
||||
*/
|
||||
static native void FindClose(long handle) throws WindowsException;
|
||||
|
||||
static QueryDirectoryInformation OpenNtQueryDirectoryInformation(String path, NativeBuffer buffer) throws WindowsException {
|
||||
NativeBuffer pathBuffer = asNativeBuffer(path);
|
||||
try {
|
||||
QueryDirectoryInformation data = new QueryDirectoryInformation();
|
||||
OpenNtQueryDirectoryInformation0(pathBuffer.address(), buffer.address(), buffer.size(), data);
|
||||
return data;
|
||||
} finally {
|
||||
pathBuffer.release();
|
||||
}
|
||||
}
|
||||
static class QueryDirectoryInformation {
|
||||
private long handle;
|
||||
private int volSerialNumber;
|
||||
|
||||
private QueryDirectoryInformation() { }
|
||||
public long handle() { return handle; }
|
||||
public int volSerialNumber() { return volSerialNumber; }
|
||||
}
|
||||
private static native void OpenNtQueryDirectoryInformation0(long lpFileName, long buffer, int bufferSize, QueryDirectoryInformation obj)
|
||||
throws WindowsException;
|
||||
|
||||
static boolean NextNtQueryDirectoryInformation(QueryDirectoryInformation data, NativeBuffer buffer) throws WindowsException {
|
||||
return NextNtQueryDirectoryInformation0(data.handle(), buffer.address(), buffer.size());
|
||||
}
|
||||
|
||||
private static native boolean NextNtQueryDirectoryInformation0(long handle, long buffer, int bufferSize)
|
||||
throws WindowsException;
|
||||
|
||||
static void CloseNtQueryDirectoryInformation(QueryDirectoryInformation data) throws WindowsException {
|
||||
CloseHandle(data.handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* GetFileInformationByHandle(
|
||||
* HANDLE hFile,
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "jni_util.h"
|
||||
#include "jlong.h"
|
||||
|
||||
#include "ntifs_min.h"
|
||||
|
||||
#include "sun_nio_fs_WindowsNativeDispatcher.h"
|
||||
|
||||
/**
|
||||
@@ -50,6 +52,9 @@ static jfieldID findFirst_attributes;
|
||||
static jfieldID findStream_handle;
|
||||
static jfieldID findStream_name;
|
||||
|
||||
static jfieldID queryDirectoryInformation_handle;
|
||||
static jfieldID queryDirectoryInformation_volSerialNumber;
|
||||
|
||||
static jfieldID volumeInfo_fsName;
|
||||
static jfieldID volumeInfo_volName;
|
||||
static jfieldID volumeInfo_volSN;
|
||||
@@ -71,6 +76,13 @@ static jfieldID completionStatus_error;
|
||||
static jfieldID completionStatus_bytesTransferred;
|
||||
static jfieldID completionStatus_completionKey;
|
||||
|
||||
typedef NTSYSCALLAPI NTSTATUS(NTAPI* NtQueryDirectoryFile_Proc) (HANDLE, HANDLE, PIO_APC_ROUTINE,
|
||||
PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN);
|
||||
typedef ULONG(NTAPI* RtlNtStatusToDosError_Proc) (NTSTATUS);
|
||||
|
||||
static NtQueryDirectoryFile_Proc NtQueryDirectoryFile_func;
|
||||
static RtlNtStatusToDosError_Proc RtlNtStatusToDosError_func;
|
||||
|
||||
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
|
||||
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
|
||||
"(I)V", lastError);
|
||||
@@ -87,6 +99,7 @@ JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
|
||||
{
|
||||
jclass clazz;
|
||||
HMODULE h;
|
||||
|
||||
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
|
||||
CHECK_NULL(clazz);
|
||||
@@ -104,6 +117,13 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
|
||||
findStream_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
|
||||
CHECK_NULL(findStream_name);
|
||||
|
||||
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$QueryDirectoryInformation");
|
||||
CHECK_NULL(clazz);
|
||||
queryDirectoryInformation_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
|
||||
CHECK_NULL(queryDirectoryInformation_handle);
|
||||
queryDirectoryInformation_volSerialNumber = (*env)->GetFieldID(env, clazz, "volSerialNumber", "I");;
|
||||
CHECK_NULL(queryDirectoryInformation_volSerialNumber);
|
||||
|
||||
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$VolumeInformation");
|
||||
CHECK_NULL(clazz);
|
||||
volumeInfo_fsName = (*env)->GetFieldID(env, clazz, "fileSystemName", "Ljava/lang/String;");
|
||||
@@ -148,6 +168,16 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
|
||||
CHECK_NULL(completionStatus_bytesTransferred);
|
||||
completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J");
|
||||
CHECK_NULL(completionStatus_completionKey);
|
||||
|
||||
// get handle to ntdll
|
||||
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
L"ntdll.dll", &h) != 0)
|
||||
{
|
||||
NtQueryDirectoryFile_func =
|
||||
(NtQueryDirectoryFile_Proc)GetProcAddress(h, "NtQueryDirectoryFile");
|
||||
RtlNtStatusToDosError_func =
|
||||
(RtlNtStatusToDosError_Proc)GetProcAddress(h, "RtlNtStatusToDosError");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
@@ -404,6 +434,118 @@ Java_sun_nio_fs_WindowsNativeDispatcher_FindClose(JNIEnv* env, jclass this,
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_WindowsNativeDispatcher_OpenNtQueryDirectoryInformation0(JNIEnv* env, jclass this,
|
||||
jlong address, jlong bufferAddress, jint bufferSize, jobject obj)
|
||||
{
|
||||
LPCWSTR lpFileName = jlong_to_ptr(address);
|
||||
BOOL ok;
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
HANDLE handle;
|
||||
NTSTATUS status;
|
||||
ULONG win32ErrorCode;
|
||||
IO_STATUS_BLOCK ioStatusBlock;
|
||||
|
||||
if ((NtQueryDirectoryFile_func == NULL) || (RtlNtStatusToDosError_func == NULL)) {
|
||||
JNU_ThrowInternalError(env, "Should not get here");
|
||||
return;
|
||||
}
|
||||
|
||||
handle = CreateFileW(lpFileName, FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
throwWindowsException(env, GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
status = NtQueryDirectoryFile_func(
|
||||
handle, // FileHandle
|
||||
NULL, // Event
|
||||
NULL, // ApcRoutine
|
||||
NULL, // ApcContext
|
||||
&ioStatusBlock, // IoStatusBlock
|
||||
jlong_to_ptr(bufferAddress), // FileInformation
|
||||
bufferSize, // Length
|
||||
FileIdFullDirectoryInformation, // FileInformationClass
|
||||
FALSE, // ReturnSingleEntry
|
||||
NULL, // FileName
|
||||
FALSE); // RestartScan
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
/*
|
||||
* NtQueryDirectoryFile returns STATUS_INVALID_PARAMETER when
|
||||
* asked to enumerate an invalid directory (ie it is a file
|
||||
* instead of a directory). Verify that is the actual cause
|
||||
* of the error.
|
||||
*/
|
||||
if (status == STATUS_INVALID_PARAMETER) {
|
||||
DWORD attributes = GetFileAttributesW(lpFileName);
|
||||
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
status = STATUS_NOT_A_DIRECTORY;
|
||||
}
|
||||
}
|
||||
|
||||
win32ErrorCode = RtlNtStatusToDosError_func(status);
|
||||
throwWindowsException(env, win32ErrorCode);
|
||||
CloseHandle(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// This call allows retrieving the volume ID of this directory (and all its entries)
|
||||
ok = GetFileInformationByHandle(handle, &info);
|
||||
if (!ok) {
|
||||
throwWindowsException(env, GetLastError());
|
||||
CloseHandle(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
(*env)->SetLongField(env, obj, queryDirectoryInformation_handle, ptr_to_jlong(handle));
|
||||
(*env)->SetIntField(env, obj, queryDirectoryInformation_volSerialNumber, info.dwVolumeSerialNumber);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_sun_nio_fs_WindowsNativeDispatcher_NextNtQueryDirectoryInformation0(JNIEnv* env, jclass this,
|
||||
jlong handle, jlong address, jint size)
|
||||
{
|
||||
HANDLE h = (HANDLE)jlong_to_ptr(handle);
|
||||
ULONG win32ErrorCode;
|
||||
IO_STATUS_BLOCK ioStatusBlock;
|
||||
NTSTATUS status;
|
||||
|
||||
if ((NtQueryDirectoryFile_func == NULL) || (RtlNtStatusToDosError_func == NULL)) {
|
||||
JNU_ThrowInternalError(env, "Should not get here");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
status = NtQueryDirectoryFile_func(
|
||||
h, // FileHandle
|
||||
NULL, // Event
|
||||
NULL, // ApcRoutine
|
||||
NULL, // ApcContext
|
||||
&ioStatusBlock, // IoStatusBlock
|
||||
jlong_to_ptr(address), // FileInformation
|
||||
size, // Length
|
||||
FileIdFullDirectoryInformation, // FileInformationClass
|
||||
FALSE, // ReturnSingleEntry
|
||||
NULL, // FileName
|
||||
FALSE); // RestartScan
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
// Normal completion: no more files in directory
|
||||
if (status == STATUS_NO_MORE_FILES) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
win32ErrorCode = RtlNtStatusToDosError_func(status);
|
||||
throwWindowsException(env, win32ErrorCode);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileInformationByHandle(JNIEnv* env, jclass this,
|
||||
jlong handle, jlong address)
|
||||
|
||||
160
src/java.base/windows/native/libnio/fs/ntifs_min.h
Normal file
160
src/java.base/windows/native/libnio/fs/ntifs_min.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _NTIFS_MIN_
|
||||
#define _NTIFS_MIN_
|
||||
|
||||
/*
|
||||
* Copy necessary structures and definitions out of the Windows DDK
|
||||
* to enable calling NtQueryDirectoryFile()
|
||||
*/
|
||||
|
||||
typedef LONG NTSTATUS;
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWCH Buffer;
|
||||
} UNICODE_STRING;
|
||||
typedef UNICODE_STRING *PUNICODE_STRING;
|
||||
typedef const UNICODE_STRING *PCUNICODE_STRING;
|
||||
|
||||
typedef enum _FILE_INFORMATION_CLASS {
|
||||
FileDirectoryInformation = 1,
|
||||
FileFullDirectoryInformation,
|
||||
FileBothDirectoryInformation,
|
||||
FileBasicInformation,
|
||||
FileStandardInformation,
|
||||
FileInternalInformation,
|
||||
FileEaInformation,
|
||||
FileAccessInformation,
|
||||
FileNameInformation,
|
||||
FileRenameInformation,
|
||||
FileLinkInformation,
|
||||
FileNamesInformation,
|
||||
FileDispositionInformation,
|
||||
FilePositionInformation,
|
||||
FileFullEaInformation,
|
||||
FileModeInformation,
|
||||
FileAlignmentInformation,
|
||||
FileAllInformation,
|
||||
FileAllocationInformation,
|
||||
FileEndOfFileInformation,
|
||||
FileAlternateNameInformation,
|
||||
FileStreamInformation,
|
||||
FilePipeInformation,
|
||||
FilePipeLocalInformation,
|
||||
FilePipeRemoteInformation,
|
||||
FileMailslotQueryInformation,
|
||||
FileMailslotSetInformation,
|
||||
FileCompressionInformation,
|
||||
FileObjectIdInformation,
|
||||
FileCompletionInformation,
|
||||
FileMoveClusterInformation,
|
||||
FileQuotaInformation,
|
||||
FileReparsePointInformation,
|
||||
FileNetworkOpenInformation,
|
||||
FileAttributeTagInformation,
|
||||
FileTrackingInformation,
|
||||
FileIdBothDirectoryInformation,
|
||||
FileIdFullDirectoryInformation,
|
||||
FileValidDataLengthInformation,
|
||||
FileShortNameInformation,
|
||||
FileIoCompletionNotificationInformation,
|
||||
FileIoStatusBlockRangeInformation,
|
||||
FileIoPriorityHintInformation,
|
||||
FileSfioReserveInformation,
|
||||
FileSfioVolumeInformation,
|
||||
FileHardLinkInformation,
|
||||
FileProcessIdsUsingFileInformation,
|
||||
FileNormalizedNameInformation,
|
||||
FileNetworkPhysicalNameInformation,
|
||||
FileIdGlobalTxDirectoryInformation,
|
||||
FileIsRemoteDeviceInformation,
|
||||
FileAttributeCacheInformation,
|
||||
FileNumaNodeInformation,
|
||||
FileStandardLinkInformation,
|
||||
FileRemoteProtocolInformation,
|
||||
FileMaximumInformation
|
||||
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _FILE_ID_FULL_DIR_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
ULONG FileIndex;
|
||||
LARGE_INTEGER CreationTime;
|
||||
LARGE_INTEGER LastAccessTime;
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
LARGE_INTEGER ChangeTime;
|
||||
LARGE_INTEGER EndOfFile;
|
||||
LARGE_INTEGER AllocationSize;
|
||||
ULONG FileAttributes;
|
||||
ULONG FileNameLength;
|
||||
ULONG EaSize;
|
||||
LARGE_INTEGER FileId;
|
||||
WCHAR FileName[1];
|
||||
} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
|
||||
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
NTSTATUS Status;
|
||||
PVOID Pointer;
|
||||
} u;
|
||||
ULONG_PTR Information;
|
||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||
|
||||
typedef VOID
|
||||
(NTAPI *PIO_APC_ROUTINE)(
|
||||
IN PVOID ApcContext,
|
||||
IN PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG Reserved);
|
||||
|
||||
NTSYSCALLAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtQueryDirectoryFile(
|
||||
_In_ HANDLE FileHandle,
|
||||
_In_opt_ HANDLE Event,
|
||||
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
|
||||
_In_opt_ PVOID ApcContext,
|
||||
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
|
||||
_Out_ PVOID FileInformation,
|
||||
_In_ ULONG Length,
|
||||
_In_ FILE_INFORMATION_CLASS FileInformationClass,
|
||||
_In_ BOOLEAN ReturnSingleEntry,
|
||||
_In_opt_ PUNICODE_STRING FileName,
|
||||
_In_ BOOLEAN RestartScan
|
||||
);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlNtStatusToDosError(
|
||||
NTSTATUS Status
|
||||
);
|
||||
|
||||
#define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L)
|
||||
#define STATUS_NOT_A_DIRECTORY ((NTSTATUS)0xC0000103L)
|
||||
|
||||
#endif // _NTIFS_MIN_
|
||||
@@ -50,6 +50,7 @@ static jclass sjc_CAccessibility = NULL;
|
||||
|
||||
NSSize getAxComponentSize(JNIEnv *env, jobject axComponent, jobject component)
|
||||
{
|
||||
GET_CACCESSIBILITY_CLASS_RETURN(NSZeroSize);
|
||||
DECLARE_CLASS_RETURN(jc_Dimension, "java/awt/Dimension", NSZeroSize);
|
||||
DECLARE_FIELD_RETURN(jf_width, jc_Dimension, "width", "I", NSZeroSize);
|
||||
DECLARE_FIELD_RETURN(jf_height, jc_Dimension, "height", "I", NSZeroSize);
|
||||
@@ -60,7 +61,10 @@ NSSize getAxComponentSize(JNIEnv *env, jobject axComponent, jobject component)
|
||||
CHECK_EXCEPTION();
|
||||
|
||||
if (dimension == NULL) return NSZeroSize;
|
||||
return NSMakeSize((*env)->GetIntField(env, dimension, jf_width), (*env)->GetIntField(env, dimension, jf_height));
|
||||
|
||||
NSSize size = NSMakeSize((*env)->GetIntField(env, dimension, jf_width), (*env)->GetIntField(env, dimension, jf_height));
|
||||
(*env)->DeleteLocalRef(env, dimension);
|
||||
return size;
|
||||
}
|
||||
|
||||
NSString *getJavaRole(JNIEnv *env, jobject axComponent, jobject component)
|
||||
@@ -253,7 +257,10 @@ NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject
|
||||
axComponent, component);
|
||||
CHECK_EXCEPTION();
|
||||
if (jpoint == NULL) return NSZeroPoint;
|
||||
return NSMakePoint((*env)->GetIntField(env, jpoint, sjf_X), (*env)->GetIntField(env, jpoint, sjf_Y));
|
||||
|
||||
NSPoint p = NSMakePoint((*env)->GetIntField(env, jpoint, sjf_X), (*env)->GetIntField(env, jpoint, sjf_Y));
|
||||
(*env)->DeleteLocalRef(env, jpoint);
|
||||
return p;
|
||||
}
|
||||
|
||||
jint getAxTextCharCount(JNIEnv *env, jobject axText, jobject component)
|
||||
|
||||
@@ -40,11 +40,18 @@ NSString* JavaStringToNSString(JNIEnv *env, jstring jstr) {
|
||||
}
|
||||
|
||||
jstring NSStringToJavaString(JNIEnv* env, NSString *str) {
|
||||
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
jstring jStr = (*env)->NewStringUTF(env, [str UTF8String]);
|
||||
jsize len = [str length];
|
||||
unichar *buffer = (unichar*)calloc(len, sizeof(unichar));
|
||||
if (buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
NSRange crange = NSMakeRange(0, len);
|
||||
[str getCharacters:buffer range:crange];
|
||||
jstring jStr = (*env)->NewString(env, buffer, len);
|
||||
free(buffer);
|
||||
CHECK_EXCEPTION();
|
||||
return jStr;
|
||||
}
|
||||
|
||||
@@ -168,8 +168,6 @@ public class XBaseWindow {
|
||||
|
||||
// Set WM_CLIENT_LEADER property
|
||||
initClientLeader();
|
||||
|
||||
initUserTimeWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -441,13 +439,6 @@ public class XBaseWindow {
|
||||
}
|
||||
}
|
||||
|
||||
private void initUserTimeWindow() {
|
||||
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
|
||||
if (netProtocol != null ) {
|
||||
netProtocol.setupUserTimeWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
static XRootWindow getXAWTRootWindow() {
|
||||
return XRootWindow.getInstance();
|
||||
}
|
||||
@@ -1314,12 +1305,18 @@ public class XBaseWindow {
|
||||
}
|
||||
|
||||
protected void setUserTime(long time, boolean updateGlobalTime) {
|
||||
setUserTime(time, updateGlobalTime, true);
|
||||
}
|
||||
|
||||
protected void setUserTime(long time, boolean updateGlobalTime, boolean updateWindowProperty) {
|
||||
if (updateGlobalTime && (int)time - (int)globalUserTime > 0 /* accounting for wrap-around */) {
|
||||
globalUserTime = time;
|
||||
}
|
||||
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
|
||||
if (netProtocol != null) {
|
||||
netProtocol.setUserTime(this, time);
|
||||
if (updateWindowProperty) {
|
||||
XNETProtocol netProtocol = XWM.getWM().getNETProtocol();
|
||||
if (netProtocol != null) {
|
||||
netProtocol.setUserTime(this, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1072,10 +1072,13 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
XClientMessageEvent cl = xev.get_xclient();
|
||||
if ((wm_protocols != null) && (cl.get_message_type() == wm_protocols.getAtom())) {
|
||||
long timestamp = getTimeStampFromClientMessage(cl);
|
||||
// we should treat WM_TAKE_FOCUS and WM_DELETE_WINDOW messages as user interaction, as they can originate
|
||||
// We should treat WM_TAKE_FOCUS and WM_DELETE_WINDOW messages as user interaction, as they can originate
|
||||
// e.g. from user clicking on window title bar and window close button correspondingly
|
||||
// (there will be no ButtonPress/ButtonRelease events in those cases)
|
||||
setUserTime(timestamp, true);
|
||||
// (there will be no ButtonPress/ButtonRelease events in those cases).
|
||||
// The received timestamp will be used to set _NET_WM_USER_TIME on newly opened windows to ensure their
|
||||
// correct focusing/positioning, but we don't set it on current window to avoid race conditions (when e.g.
|
||||
// WM_TAKE_FOCUS arrives around the time of new window opening).
|
||||
setUserTime(timestamp, true, false);
|
||||
|
||||
if (cl.get_data(0) == wm_delete_window.getAtom()) {
|
||||
handleQuit();
|
||||
|
||||
@@ -287,7 +287,6 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
|
||||
XAtom XA_NET_WM_WINDOW_OPACITY = XAtom.get("_NET_WM_WINDOW_OPACITY");
|
||||
|
||||
XAtom XA_NET_WM_USER_TIME = XAtom.get("_NET_WM_USER_TIME");
|
||||
XAtom XA_NET_WM_USER_TIME_WINDOW = XAtom.get("_NET_WM_USER_TIME_WINDOW");
|
||||
|
||||
/* For _NET_WM_STATE ClientMessage requests */
|
||||
static final int _NET_WM_STATE_REMOVE =0; /* remove/unset property */
|
||||
@@ -460,20 +459,9 @@ final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProt
|
||||
return (state != null && state.size() != 0 && state.contains(XA_NET_WM_STATE_HIDDEN));
|
||||
}
|
||||
|
||||
private boolean isUserTimeWindowSupported() {
|
||||
return checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_USER_TIME_WINDOW);
|
||||
}
|
||||
|
||||
void setupUserTimeWindow(XBaseWindow window) {
|
||||
if (active() && isUserTimeWindowSupported()) {
|
||||
XA_NET_WM_USER_TIME_WINDOW.setWindowProperty(window, XRootWindow.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
void setUserTime(XBaseWindow window, long time) {
|
||||
if (active()) {
|
||||
XBaseWindow target = isUserTimeWindowSupported() ? XRootWindow.getInstance() : window;
|
||||
XA_NET_WM_USER_TIME.setCard32Property(target, time);
|
||||
XA_NET_WM_USER_TIME.setCard32Property(window, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,10 +168,6 @@ final class WInputMethod extends InputMethodAdapter
|
||||
|
||||
@Override
|
||||
public boolean setLocale(Locale lang) {
|
||||
return setLocale(lang, false);
|
||||
}
|
||||
|
||||
private boolean setLocale(Locale lang, boolean onActivate) {
|
||||
Locale[] available = WInputMethodDescriptor.getAvailableLocalesInternal();
|
||||
for (int i = 0; i < available.length; i++) {
|
||||
Locale locale = available[i];
|
||||
@@ -180,7 +176,7 @@ final class WInputMethod extends InputMethodAdapter
|
||||
locale.equals(Locale.JAPAN) && lang.equals(Locale.JAPANESE) ||
|
||||
locale.equals(Locale.KOREA) && lang.equals(Locale.KOREAN)) {
|
||||
if (isActive) {
|
||||
setNativeLocale(locale.toLanguageTag(), onActivate);
|
||||
setNativeLocale(locale.toLanguageTag());
|
||||
}
|
||||
currentLocale = locale;
|
||||
return true;
|
||||
@@ -319,9 +315,6 @@ final class WInputMethod extends InputMethodAdapter
|
||||
isLastFocussedActiveClient = isAc;
|
||||
}
|
||||
isActive = true;
|
||||
if (currentLocale != null) {
|
||||
setLocale(currentLocale, true);
|
||||
}
|
||||
|
||||
// Compare IM's composition string with Java's composition string
|
||||
if (hasCompositionString && !isCompositionStringAvailable(context)) {
|
||||
@@ -348,10 +341,6 @@ final class WInputMethod extends InputMethodAdapter
|
||||
@Override
|
||||
public void deactivate(boolean isTemporary)
|
||||
{
|
||||
// Sync currentLocale with the Windows keyboard layout which might be changed
|
||||
// by hot key
|
||||
getLocale();
|
||||
|
||||
// Delay calling disableNativeIME until activate is called and the newly
|
||||
// focussed component has a different peer as the last focussed component.
|
||||
if (awtFocussedComponentPeer != null) {
|
||||
@@ -667,7 +656,7 @@ final class WInputMethod extends InputMethodAdapter
|
||||
private native void setStatusWindowVisible(WComponentPeer peer, boolean visible);
|
||||
private native String getNativeIMMDescription();
|
||||
static native Locale getNativeLocale();
|
||||
static native boolean setNativeLocale(String localeName, boolean onActivate);
|
||||
static native boolean setNativeLocale(String localeName);
|
||||
private native void openCandidateWindow(WComponentPeer peer, int x, int y);
|
||||
private native boolean isCompositionStringAvailable(int context);
|
||||
}
|
||||
|
||||
@@ -88,15 +88,6 @@ static DCList passiveDCList;
|
||||
|
||||
extern void CheckFontSmoothingSettings(HWND);
|
||||
|
||||
extern "C" {
|
||||
// Remember the input language has changed by some user's action
|
||||
// (Alt+Shift or through the language icon on the Taskbar) to control the
|
||||
// race condition between the toolkit thread and the AWT event thread.
|
||||
// This flag remains TRUE until the next WInputMethod.getNativeLocale() is
|
||||
// issued.
|
||||
BOOL g_bUserHasChangedInputLang = FALSE;
|
||||
}
|
||||
|
||||
BOOL AwtComponent::sm_suppressFocusAndActivation = FALSE;
|
||||
BOOL AwtComponent::sm_restoreFocusAndActivation = FALSE;
|
||||
HWND AwtComponent::sm_focusOwner = NULL;
|
||||
@@ -1900,9 +1891,6 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
::ToAsciiEx(VK_SPACE, ::MapVirtualKey(VK_SPACE, 0),
|
||||
keyboardState, &ignored, 0, GetKeyboardLayout());
|
||||
|
||||
// Set this flag to block ActivateKeyboardLayout from
|
||||
// WInputMethod.activate()
|
||||
g_bUserHasChangedInputLang = TRUE;
|
||||
CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
|
||||
break;
|
||||
}
|
||||
@@ -1911,7 +1899,6 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
"new = 0x%08X",
|
||||
GetHWnd(), GetClassName(), (UINT)lParam);
|
||||
mr = WmInputLangChange(static_cast<UINT>(wParam), reinterpret_cast<HKL>(lParam));
|
||||
g_bUserHasChangedInputLang = TRUE;
|
||||
CallProxyDefWindowProc(message, wParam, lParam, retValue, mr);
|
||||
// should return non-zero if we process this message
|
||||
retValue = 1;
|
||||
|
||||
@@ -44,8 +44,6 @@ extern "C" {
|
||||
jobject CreateLocaleObject(JNIEnv *env, const char * name);
|
||||
HKL getDefaultKeyboardLayout();
|
||||
|
||||
extern BOOL g_bUserHasChangedInputLang;
|
||||
|
||||
/*
|
||||
* Class: sun_awt_windows_WInputMethod
|
||||
* Method: createNativeContext
|
||||
@@ -292,10 +290,6 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WInputMethod_getNativeLocale
|
||||
|
||||
const char * javaLocaleName = getJavaIDFromLangID(AwtComponent::GetInputLanguage());
|
||||
if (javaLocaleName != NULL) {
|
||||
// Now WInputMethod.currentLocale and AwtComponent::m_idLang are get sync'ed,
|
||||
// so we can reset this flag.
|
||||
g_bUserHasChangedInputLang = FALSE;
|
||||
|
||||
jobject ret = CreateLocaleObject(env, javaLocaleName);
|
||||
free((void *)javaLocaleName);
|
||||
return ret;
|
||||
@@ -309,10 +303,10 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WInputMethod_getNativeLocale
|
||||
/*
|
||||
* Class: sun_awt_windows_WInputMethod
|
||||
* Method: setNativeLocale
|
||||
* Signature: (Ljava/lang/String;Z)Z
|
||||
* Signature: (Ljava/lang/String;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
|
||||
(JNIEnv *env, jclass cls, jstring localeString, jboolean onActivate)
|
||||
(JNIEnv *env, jclass cls, jstring localeString)
|
||||
{
|
||||
TRY;
|
||||
|
||||
@@ -353,7 +347,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
|
||||
if (supported != NULL) {
|
||||
if (strcmp(supported, requested) == 0) {
|
||||
// use special message to call ActivateKeyboardLayout() in main thread.
|
||||
if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, (WPARAM)onActivate, (LPARAM)hKLList[i])) {
|
||||
if (AwtToolkit::GetInstance().SendMessage(WM_AWT_ACTIVATEKEYBOARDLAYOUT, 0, (LPARAM)hKLList[i])) {
|
||||
//also need to change the same keyboard layout for the Java AWT-EventQueue thread
|
||||
AwtToolkit::activateKeyboardLayout(hKLList[i]);
|
||||
retValue = JNI_TRUE;
|
||||
|
||||
@@ -71,7 +71,6 @@ extern void initScreens(JNIEnv *env);
|
||||
extern "C" void awt_dnd_initialize();
|
||||
extern "C" void awt_dnd_uninitialize();
|
||||
extern "C" void awt_clipboard_uninitialize(JNIEnv *env);
|
||||
extern "C" BOOL g_bUserHasChangedInputLang;
|
||||
|
||||
extern CriticalSection windowMoveLock;
|
||||
extern BOOL windowMoveLockHeld;
|
||||
@@ -1235,14 +1234,6 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
return cmode;
|
||||
}
|
||||
case WM_AWT_ACTIVATEKEYBOARDLAYOUT: {
|
||||
if (wParam && g_bUserHasChangedInputLang) {
|
||||
// Input language has been changed since the last WInputMethod.getNativeLocale()
|
||||
// call. So let's honor the user's selection.
|
||||
// Note: we need to check this flag inside the toolkit thread to synchronize access
|
||||
// to the flag.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lParam == (LPARAM)::GetKeyboardLayout(0)) {
|
||||
// already active
|
||||
return FALSE;
|
||||
|
||||
100
test/jdk/java/awt/event/KeyEvent/KeyTyped/CtrlSpace.java
Normal file
100
test/jdk/java/awt/event/KeyEvent/KeyTyped/CtrlSpace.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
@test
|
||||
@key headful
|
||||
@bug 8272602
|
||||
@summary Ctrl+Space should generate a KeyTyped event on macOS
|
||||
@run main CtrlSpace
|
||||
*/
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Panel;
|
||||
import java.awt.TextField;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
|
||||
public class CtrlSpace extends Frame implements KeyListener {
|
||||
|
||||
static volatile boolean testPassed = false;
|
||||
static volatile Robot robot;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
robot = new Robot();
|
||||
robot.setAutoWaitForIdle(true);
|
||||
robot.setAutoDelay(100);
|
||||
|
||||
Frame frame = createAndShowGUI(robot);
|
||||
|
||||
test(robot);
|
||||
robot.waitForIdle();
|
||||
Thread.sleep(2000);
|
||||
frame.setVisible(false);
|
||||
frame.dispose();
|
||||
if (!testPassed) {
|
||||
throw new RuntimeException("No KeyTyped event");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Frame createAndShowGUI(Robot robot) {
|
||||
CtrlSpace win = new CtrlSpace();
|
||||
win.setSize(300, 300);
|
||||
Panel panel = new Panel(new BorderLayout());
|
||||
TextField textField = new TextField("abcdefghijk");
|
||||
textField.addKeyListener(win);
|
||||
panel.add(textField, BorderLayout.CENTER);
|
||||
win.add(panel);
|
||||
win.setVisible(true);
|
||||
robot.waitForIdle();
|
||||
textField.requestFocusInWindow();
|
||||
robot.waitForIdle();
|
||||
return win;
|
||||
}
|
||||
|
||||
public static void test(Robot robot) {
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_SPACE);
|
||||
robot.keyRelease(KeyEvent.VK_SPACE);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
robot.delay(200);
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent evt) {
|
||||
System.out.println("Pressed " + evt);
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent evt) {
|
||||
System.out.println("Released " + evt);
|
||||
}
|
||||
|
||||
public void keyTyped(KeyEvent evt) {
|
||||
System.out.println("Typed " + evt);
|
||||
testPassed = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4313887 6873621 6979526 7006126 7020517
|
||||
* @bug 4313887 6873621 6979526 7006126 7020517 8264400
|
||||
* @summary Unit test for java.nio.file.FileStore
|
||||
* @key intermittent
|
||||
* @library .. /test/lib
|
||||
@@ -36,9 +36,9 @@ import java.nio.file.attribute.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.util.FileUtils;
|
||||
|
||||
|
||||
public class Basic {
|
||||
|
||||
static final long G = 1024L * 1024L * 1024L;
|
||||
@@ -80,6 +80,15 @@ public class Basic {
|
||||
assertTrue(store2.equals(store1));
|
||||
assertTrue(store1.hashCode() == store2.hashCode());
|
||||
|
||||
if (Platform.isWindows()) {
|
||||
/**
|
||||
* Test: FileStore.equals() should not be case sensitive
|
||||
*/
|
||||
FileStore upper = Files.getFileStore(Path.of("C:\\"));
|
||||
FileStore lower = Files.getFileStore(Path.of("c:\\"));
|
||||
assertTrue(lower.equals(upper));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: File and FileStore attributes
|
||||
*/
|
||||
|
||||
@@ -42,6 +42,8 @@ import java.nio.file.WatchService;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
import java.nio.file.attribute.FileAttributeView;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.nio.file.attribute.BasicFileAttributeView;
|
||||
import java.nio.file.attribute.UserPrincipalLookupService;
|
||||
import java.nio.file.spi.FileSystemProvider;
|
||||
import java.util.Iterator;
|
||||
@@ -323,12 +325,44 @@ class FaultyFileSystem extends FileSystem {
|
||||
return Files.readAttributes(unwrap(file), attributes, options);
|
||||
}
|
||||
|
||||
private class FaultyBasicFileAttributeView implements BasicFileAttributeView {
|
||||
private final Path file;
|
||||
private final LinkOption[] options;
|
||||
|
||||
public FaultyBasicFileAttributeView(final Path file, final LinkOption... options) {
|
||||
this.file = file;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "faulty";
|
||||
}
|
||||
|
||||
@Override
|
||||
public BasicFileAttributes readAttributes() throws IOException {
|
||||
triggerEx(file, "readAttributes");
|
||||
return Files.readAttributes(file, BasicFileAttributes.class, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimes(FileTime lastModifiedTime,
|
||||
FileTime lastAccessTime,
|
||||
FileTime createTime) throws IOException {
|
||||
triggerEx(file, "setTimes");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V extends FileAttributeView> V getFileAttributeView(Path file,
|
||||
Class<V> type,
|
||||
LinkOption... options)
|
||||
{
|
||||
return Files.getFileAttributeView(unwrap(file), type, options);
|
||||
if (type != BasicFileAttributeView.class) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (V)new FaultyBasicFileAttributeView(unwrap(file), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
80
test/jdk/java/nio/file/Files/walkFileTree/NonLatin.java
Normal file
80
test/jdk/java/nio/file/Files/walkFileTree/NonLatin.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, JetBrains s.r.o.. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Tests that walkFileTree can find files in a directory with
|
||||
* non-latin characters in the name (including ones from
|
||||
* the supplementary plane)
|
||||
* @library /test/lib
|
||||
*/
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.FileVisitOption;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Vector;
|
||||
import java.util.HashSet;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
public class NonLatin {
|
||||
// Use non-Latin characters from basic (\u1889) and supplementary (\uD844\uDDD9) Unicode planes
|
||||
private static final String NON_LATIN_PATH_NAME = "ka-\u1889-supp-\uD844\uDDD9";
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
final Path currentDirPath = Paths.get(".").toAbsolutePath();
|
||||
Path nonLatinPath = null;
|
||||
|
||||
try {
|
||||
nonLatinPath = currentDirPath.resolve(NON_LATIN_PATH_NAME);
|
||||
Files.createDirectory(nonLatinPath);
|
||||
final Path underNonLatinPath = nonLatinPath.resolve("dir");
|
||||
Files.createDirectory(underNonLatinPath);
|
||||
} catch (java.nio.file.InvalidPathException e) {
|
||||
System.out.println("Cannot create the directory with the right name. Test is considered passed");
|
||||
return;
|
||||
}
|
||||
|
||||
final Vector<String> visitedDirs = new Vector<String>();
|
||||
|
||||
Files.walkFileTree(nonLatinPath, new HashSet<FileVisitOption>(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
|
||||
visitedDirs.add(dir.toString());
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
|
||||
boolean found = false;
|
||||
for (final String dirName : visitedDirs) {
|
||||
System.out.println("Found: " + dirName);
|
||||
found |= dirName.contains(NON_LATIN_PATH_NAME);
|
||||
}
|
||||
Asserts.assertTrue(found);
|
||||
}
|
||||
}
|
||||
@@ -244,20 +244,23 @@ public class CustomComboBoxFocusTest {
|
||||
System.out.println("Request focus on " + target);
|
||||
final Component c = target.getEditor().getEditorComponent();
|
||||
|
||||
c.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
SwingUtilities.invokeLater(focusHandler);
|
||||
}
|
||||
if (c.isFocusOwner()) {
|
||||
SwingUtilities.invokeLater(focusHandler);
|
||||
} else {
|
||||
c.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
SwingUtilities.invokeLater(focusHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
c.requestFocus();
|
||||
}
|
||||
});
|
||||
|
||||
c.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
public Step nextStep() {
|
||||
|
||||
@@ -45,6 +45,7 @@ public class TypeaheadRequestFocusTest {
|
||||
initFinished.get(10, TimeUnit.SECONDS);
|
||||
clickOn(frameField);
|
||||
SwingUtilities.invokeAndWait(TypeaheadRequestFocusTest::showPopup);
|
||||
robot.delay(1000);
|
||||
pressAndRelease(KeyEvent.VK_ENTER);
|
||||
pressAndRelease(KeyEvent.VK_A);
|
||||
typedInPopup.get(10, TimeUnit.SECONDS);
|
||||
|
||||
@@ -61,13 +61,11 @@ public class NestedDialogHideTest {
|
||||
button3 = new JButton("Hide");
|
||||
button3.addActionListener(eee -> d.setVisible(false));
|
||||
d2.add(button3);
|
||||
d2.pack();
|
||||
d2.setLocation(240, 240);
|
||||
d2.setBounds(240, 240, 200, 200);
|
||||
d2.setVisible(true);
|
||||
});
|
||||
d.add(button2);
|
||||
d.pack();
|
||||
d.setLocation(220, 220);
|
||||
d.setBounds(220, 220, 200, 200);
|
||||
d.setVisible(true);
|
||||
d.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
@@ -77,8 +75,7 @@ public class NestedDialogHideTest {
|
||||
});
|
||||
});
|
||||
frame.add(button1);
|
||||
frame.pack();
|
||||
frame.setLocation(200, 200);
|
||||
frame.setBounds(200, 200, 200, 200);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
28
test/jdk/jbA11yProblemList.txt
Normal file
28
test/jdk/jbA11yProblemList.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
java/awt/Focus/ModalDialogInitialFocusTest/ModalDialogInitialFocusTest.java JBR-3730 macosx-all
|
||||
java/awt/Choice/UnfocusableCB_ERR/UnfocusableCB_ERR.java JBR-3730 macosx-all
|
||||
java/awt/Component/7097771/bug7097771.java JBR-3730 macosx-all
|
||||
java/awt/Component/NoUpdateUponShow/NoUpdateUponShow.java JBR-3730 macosx-all
|
||||
java/awt/Component/PaintAll/PaintAll.java JBR-3730 macosx-all
|
||||
java/awt/Focus/DisposedWindow/DisposeDialogNotActivateOwnerTest/DisposeDialogNotActivateOwnerTest.java JBR-3730 macosx-all
|
||||
java/awt/Focus/ModalDialogInitialFocusTest/ModalDialogInitialFocusTest.html JBR-3730 macosx-all
|
||||
java/awt/Focus/NonFocusableWindowTest/NoEventsTest.java JBR-3730 macosx-all
|
||||
java/awt/Focus/RemoveAfterRequest/RemoveAfterRequest.java JBR-3730 macosx-all
|
||||
java/awt/Focus/RequestFocusAndHideTest/RequestFocusAndHideTest.java JBR-3730 macosx-all
|
||||
java/awt/Focus/RequestOnCompWithNullParent/RequestOnCompWithNullParent1.java JBR-3730 macosx-all
|
||||
java/awt/Focus/RestoreFocusOnDisabledComponentTest/RestoreFocusOnDisabledComponentTest.java JBR-3730 macosx-all
|
||||
java/awt/Frame/ObscuredFrame/ObscuredFrameTest.java JBR-3730 macosx-all
|
||||
java/awt/Focus/WindowIsFocusableAccessByThreadsTest/WindowIsFocusableAccessByThreadsTest.java JBR-3730 macosx-all
|
||||
java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java JBR-3730 macosx-all
|
||||
java/awt/Frame/MiscUndecorated/FrameCloseTest.java JBR-3733 macosx-all
|
||||
java/awt/Frame/ObscuredFrame/ObscuredFrameTest.java JBR-3730 macosx-all
|
||||
java/awt/Frame/ResizeAfterSetFont/ResizeAfterSetFont.java JBR-3730 macosx-all
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/EnqueueWithDialogTest/EnqueueWithDialogTest.java JBR-3730 macosx-all
|
||||
java/awt/Mixing/Validating.java JBR-3730 macosx-all
|
||||
java/awt/Mixing/ValidBounds.java JBR-3730 macosx-all
|
||||
java/awt/MouseAdapter/MouseAdapterUnitTest/MouseAdapterUnitTest.java JBR-3730 macosx-all
|
||||
java/awt/print/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java JBR-3730 macosx-all
|
||||
java/awt/event/ComponentEvent/MovedResizedTwiceTest/MovedResizedTwiceTest.java JBR-3730 macosx-all
|
||||
java/awt/event/MouseEvent/EnterAsGrabbedEvent/EnterAsGrabbedEvent.java JBR-3730 macosx-all
|
||||
java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.html JBR-3730 macosx-all
|
||||
java/awt/event/MouseEvent/MouseButtonsTest/MouseButtonsTest.java JBR-3730 macosx-all
|
||||
java/awt/event/MouseEvent/MultipleMouseButtonsTest/MultipleMouseButtonsTest.java JBR-3730 macosx-all
|
||||
Reference in New Issue
Block a user