8154208: (fs) Drop code for Windows XP/2003 from file system provider
Reviewed-by: bpb, alanb
This commit is contained in:
parent
44613235d7
commit
07b96dfbd1
@ -79,7 +79,7 @@ class WindowsFileAttributeViews {
|
|||||||
long handle = -1L;
|
long handle = -1L;
|
||||||
try {
|
try {
|
||||||
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||||
if (!followLinks && file.getFileSystem().supportsLinks())
|
if (!followLinks)
|
||||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||||
|
|
||||||
handle = CreateFile(file.getPathForWin32Calls(),
|
handle = CreateFile(file.getPathForWin32Calls(),
|
||||||
|
@ -168,9 +168,7 @@ class WindowsFileCopy {
|
|||||||
|
|
||||||
// Use CopyFileEx if the file is not a directory or junction
|
// Use CopyFileEx if the file is not a directory or junction
|
||||||
if (!sourceAttrs.isDirectory() && !sourceAttrs.isDirectoryLink()) {
|
if (!sourceAttrs.isDirectory() && !sourceAttrs.isDirectoryLink()) {
|
||||||
final int flags =
|
final int flags = (!followLinks) ? COPY_FILE_COPY_SYMLINK : 0;
|
||||||
(source.getFileSystem().supportsLinks() && !followLinks) ?
|
|
||||||
COPY_FILE_COPY_SYMLINK : 0;
|
|
||||||
|
|
||||||
if (interruptible) {
|
if (interruptible) {
|
||||||
// interruptible copy
|
// interruptible copy
|
||||||
|
@ -78,14 +78,7 @@ class WindowsFileStore
|
|||||||
// if the file is a link then GetVolumePathName returns the
|
// if the file is a link then GetVolumePathName returns the
|
||||||
// volume that the link is on so we need to call it with the
|
// volume that the link is on so we need to call it with the
|
||||||
// final target
|
// final target
|
||||||
String target;
|
String target = WindowsLinkSupport.getFinalPath(file, true);
|
||||||
if (file.getFileSystem().supportsLinks()) {
|
|
||||||
target = WindowsLinkSupport.getFinalPath(file, true);
|
|
||||||
} else {
|
|
||||||
// file must exist
|
|
||||||
WindowsFileAttributes.get(file, true);
|
|
||||||
target = file.getPathForWin32Calls();
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return createFromPath(target);
|
return createFromPath(target);
|
||||||
} catch (WindowsException e) {
|
} catch (WindowsException e) {
|
||||||
|
@ -31,9 +31,6 @@ import java.nio.file.spi.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import sun.security.action.GetPropertyAction;
|
|
||||||
|
|
||||||
class WindowsFileSystem
|
class WindowsFileSystem
|
||||||
extends FileSystem
|
extends FileSystem
|
||||||
@ -44,9 +41,6 @@ class WindowsFileSystem
|
|||||||
private final String defaultDirectory;
|
private final String defaultDirectory;
|
||||||
private final String defaultRoot;
|
private final String defaultRoot;
|
||||||
|
|
||||||
private final boolean supportsLinks;
|
|
||||||
private final boolean supportsStreamEnumeration;
|
|
||||||
|
|
||||||
// package-private
|
// package-private
|
||||||
WindowsFileSystem(WindowsFileSystemProvider provider,
|
WindowsFileSystem(WindowsFileSystemProvider provider,
|
||||||
String dir)
|
String dir)
|
||||||
@ -61,18 +55,6 @@ class WindowsFileSystem
|
|||||||
throw new AssertionError("Default directory is not an absolute path");
|
throw new AssertionError("Default directory is not an absolute path");
|
||||||
this.defaultDirectory = result.path();
|
this.defaultDirectory = result.path();
|
||||||
this.defaultRoot = result.root();
|
this.defaultRoot = result.root();
|
||||||
|
|
||||||
PrivilegedAction<String> pa = new GetPropertyAction("os.version");
|
|
||||||
String osversion = AccessController.doPrivileged(pa);
|
|
||||||
String[] vers = Util.split(osversion, '.');
|
|
||||||
int major = Integer.parseInt(vers[0]);
|
|
||||||
int minor = Integer.parseInt(vers[1]);
|
|
||||||
|
|
||||||
// symbolic links available on Vista and newer
|
|
||||||
supportsLinks = (major >= 6);
|
|
||||||
|
|
||||||
// enumeration of data streams available on Windows Server 2003 and newer
|
|
||||||
supportsStreamEnumeration = (major >= 6) || (major == 5 && minor >= 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// package-private
|
// package-private
|
||||||
@ -84,14 +66,6 @@ class WindowsFileSystem
|
|||||||
return defaultRoot;
|
return defaultRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean supportsLinks() {
|
|
||||||
return supportsLinks;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean supportsStreamEnumeration() {
|
|
||||||
return supportsStreamEnumeration;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileSystemProvider provider() {
|
public FileSystemProvider provider() {
|
||||||
return provider;
|
return provider;
|
||||||
|
@ -526,11 +526,6 @@ public class WindowsFileSystemProvider
|
|||||||
WindowsPath link = WindowsPath.toWindowsPath(obj1);
|
WindowsPath link = WindowsPath.toWindowsPath(obj1);
|
||||||
WindowsPath target = WindowsPath.toWindowsPath(obj2);
|
WindowsPath target = WindowsPath.toWindowsPath(obj2);
|
||||||
|
|
||||||
if (!link.getFileSystem().supportsLinks()) {
|
|
||||||
throw new UnsupportedOperationException("Symbolic links not supported "
|
|
||||||
+ "on this operating system");
|
|
||||||
}
|
|
||||||
|
|
||||||
// no attributes allowed
|
// no attributes allowed
|
||||||
if (attrs.length > 0) {
|
if (attrs.length > 0) {
|
||||||
WindowsSecurityDescriptor.fromAttribute(attrs); // may throw NPE or UOE
|
WindowsSecurityDescriptor.fromAttribute(attrs); // may throw NPE or UOE
|
||||||
@ -614,9 +609,6 @@ public class WindowsFileSystemProvider
|
|||||||
public Path readSymbolicLink(Path obj1) throws IOException {
|
public Path readSymbolicLink(Path obj1) throws IOException {
|
||||||
WindowsPath link = WindowsPath.toWindowsPath(obj1);
|
WindowsPath link = WindowsPath.toWindowsPath(obj1);
|
||||||
WindowsFileSystem fs = link.getFileSystem();
|
WindowsFileSystem fs = link.getFileSystem();
|
||||||
if (!fs.supportsLinks()) {
|
|
||||||
throw new UnsupportedOperationException("symbolic links not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
// permission check
|
// permission check
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
@ -96,7 +96,7 @@ class WindowsLinkSupport {
|
|||||||
WindowsFileSystem fs = input.getFileSystem();
|
WindowsFileSystem fs = input.getFileSystem();
|
||||||
try {
|
try {
|
||||||
// if not following links then don't need final path
|
// if not following links then don't need final path
|
||||||
if (!followLinks || !fs.supportsLinks())
|
if (!followLinks)
|
||||||
return input.getPathForWin32Calls();
|
return input.getPathForWin32Calls();
|
||||||
|
|
||||||
// if file is not a sym link then don't need final path
|
// if file is not a sym link then don't need final path
|
||||||
@ -157,8 +157,6 @@ class WindowsLinkSupport {
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
WindowsFileSystem fs = input.getFileSystem();
|
WindowsFileSystem fs = input.getFileSystem();
|
||||||
if (resolveLinks && !fs.supportsLinks())
|
|
||||||
resolveLinks = false;
|
|
||||||
|
|
||||||
// Start with absolute path
|
// Start with absolute path
|
||||||
String path = null;
|
String path = null;
|
||||||
|
@ -1071,54 +1071,6 @@ class WindowsNativeDispatcher {
|
|||||||
static native int GetOverlappedResult(long hFile, long lpOverlapped)
|
static native int GetOverlappedResult(long hFile, long lpOverlapped)
|
||||||
throws WindowsException;
|
throws WindowsException;
|
||||||
|
|
||||||
/**
|
|
||||||
* BackupRead(
|
|
||||||
* HANDLE hFile,
|
|
||||||
* LPBYTE lpBuffer,
|
|
||||||
* DWORD nNumberOfBytesToRead,
|
|
||||||
* LPDWORD lpNumberOfBytesRead,
|
|
||||||
* BOOL bAbort,
|
|
||||||
* BOOL bProcessSecurity,
|
|
||||||
* LPVOID* lpContext
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
static BackupResult BackupRead(long hFile,
|
|
||||||
long bufferAddress,
|
|
||||||
int bufferSize,
|
|
||||||
boolean abort,
|
|
||||||
long context)
|
|
||||||
throws WindowsException
|
|
||||||
{
|
|
||||||
BackupResult result = new BackupResult();
|
|
||||||
BackupRead0(hFile, bufferAddress, bufferSize, abort, context, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
static class BackupResult {
|
|
||||||
private int bytesTransferred;
|
|
||||||
private long context;
|
|
||||||
private BackupResult() { }
|
|
||||||
|
|
||||||
int bytesTransferred() { return bytesTransferred; }
|
|
||||||
long context() { return context; }
|
|
||||||
}
|
|
||||||
private static native void BackupRead0(long hFile, long bufferAddress,
|
|
||||||
int bufferSize, boolean abort, long context, BackupResult result)
|
|
||||||
throws WindowsException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BackupSeek(
|
|
||||||
* HANDLE hFile,
|
|
||||||
* DWORD dwLowBytesToSeek,
|
|
||||||
* DWORD dwHighBytesToSeek,
|
|
||||||
* LPDWORD lpdwLowByteSeeked,
|
|
||||||
* LPDWORD lpdwHighByteSeeked,
|
|
||||||
* LPVOID* lpContext
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
static native void BackupSeek(long hFile, long bytesToSeek, long context)
|
|
||||||
throws WindowsException;
|
|
||||||
|
|
||||||
|
|
||||||
// -- support for copying String with a NativeBuffer --
|
// -- support for copying String with a NativeBuffer --
|
||||||
|
|
||||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||||
|
@ -780,7 +780,7 @@ class WindowsPath implements Path {
|
|||||||
throws WindowsException
|
throws WindowsException
|
||||||
{
|
{
|
||||||
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||||
if (!followLinks && getFileSystem().supportsLinks())
|
if (!followLinks)
|
||||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||||
return CreateFile(getPathForWin32Calls(),
|
return CreateFile(getPathForWin32Calls(),
|
||||||
FILE_READ_ATTRIBUTES,
|
FILE_READ_ATTRIBUTES,
|
||||||
|
@ -91,121 +91,11 @@ class WindowsUserDefinedFileAttributeView
|
|||||||
return Collections.unmodifiableList(list);
|
return Collections.unmodifiableList(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
// enumerates the file streams by reading the stream headers using
|
|
||||||
// BackupRead
|
|
||||||
private List<String> listUsingBackupRead() throws IOException {
|
|
||||||
long handle = -1L;
|
|
||||||
try {
|
|
||||||
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
|
||||||
if (!followLinks && file.getFileSystem().supportsLinks())
|
|
||||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
|
||||||
|
|
||||||
handle = CreateFile(file.getPathForWin32Calls(),
|
|
||||||
GENERIC_READ,
|
|
||||||
FILE_SHARE_READ, // no write as we depend on file size
|
|
||||||
OPEN_EXISTING,
|
|
||||||
flags);
|
|
||||||
} catch (WindowsException x) {
|
|
||||||
x.rethrowAsIOException(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// buffer to read stream header and stream name.
|
|
||||||
final int BUFFER_SIZE = 4096;
|
|
||||||
NativeBuffer buffer = null;
|
|
||||||
|
|
||||||
// result with names of alternative data streams
|
|
||||||
final List<String> list = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
buffer = NativeBuffers.getNativeBuffer(BUFFER_SIZE);
|
|
||||||
long address = buffer.address();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* typedef struct _WIN32_STREAM_ID {
|
|
||||||
* DWORD dwStreamId;
|
|
||||||
* DWORD dwStreamAttributes;
|
|
||||||
* LARGE_INTEGER Size;
|
|
||||||
* DWORD dwStreamNameSize;
|
|
||||||
* WCHAR cStreamName[ANYSIZE_ARRAY];
|
|
||||||
* } WIN32_STREAM_ID;
|
|
||||||
*/
|
|
||||||
final int SIZEOF_STREAM_HEADER = 20;
|
|
||||||
final int OFFSETOF_STREAM_ID = 0;
|
|
||||||
final int OFFSETOF_STREAM_SIZE = 8;
|
|
||||||
final int OFFSETOF_STREAM_NAME_SIZE = 16;
|
|
||||||
|
|
||||||
long context = 0L;
|
|
||||||
try {
|
|
||||||
for (;;) {
|
|
||||||
// read stream header
|
|
||||||
BackupResult result = BackupRead(handle, address,
|
|
||||||
SIZEOF_STREAM_HEADER, false, context);
|
|
||||||
context = result.context();
|
|
||||||
if (result.bytesTransferred() == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
int streamId = unsafe.getInt(address + OFFSETOF_STREAM_ID);
|
|
||||||
long streamSize = unsafe.getLong(address + OFFSETOF_STREAM_SIZE);
|
|
||||||
int nameSize = unsafe.getInt(address + OFFSETOF_STREAM_NAME_SIZE);
|
|
||||||
|
|
||||||
// read stream name
|
|
||||||
if (nameSize > 0) {
|
|
||||||
result = BackupRead(handle, address, nameSize, false, context);
|
|
||||||
if (result.bytesTransferred() != nameSize)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for alternative data stream
|
|
||||||
if (streamId == BACKUP_ALTERNATE_DATA) {
|
|
||||||
char[] nameAsArray = new char[nameSize/2];
|
|
||||||
unsafe.copyMemory(null, address, nameAsArray,
|
|
||||||
Unsafe.ARRAY_CHAR_BASE_OFFSET, nameSize);
|
|
||||||
|
|
||||||
String[] segs = new String(nameAsArray).split(":");
|
|
||||||
if (segs.length == 3)
|
|
||||||
list.add(segs[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sparse blocks not currently handled as documentation
|
|
||||||
// is not sufficient on how the spase block can be skipped.
|
|
||||||
if (streamId == BACKUP_SPARSE_BLOCK) {
|
|
||||||
throw new IOException("Spare blocks not handled");
|
|
||||||
}
|
|
||||||
|
|
||||||
// seek to end of stream
|
|
||||||
if (streamSize > 0L) {
|
|
||||||
BackupSeek(handle, streamSize, context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (WindowsException x) {
|
|
||||||
// failed to read or seek
|
|
||||||
throw new IOException(x.errorString());
|
|
||||||
} finally {
|
|
||||||
// release context
|
|
||||||
if (context != 0L) {
|
|
||||||
try {
|
|
||||||
BackupRead(handle, 0L, 0, true, context);
|
|
||||||
} catch (WindowsException ignore) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (buffer != null)
|
|
||||||
buffer.release();
|
|
||||||
CloseHandle(handle);
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableList(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> list() throws IOException {
|
public List<String> list() throws IOException {
|
||||||
if (System.getSecurityManager() != null)
|
if (System.getSecurityManager() != null)
|
||||||
checkAccess(file.getPathForPermissionCheck(), true, false);
|
checkAccess(file.getPathForPermissionCheck(), true, false);
|
||||||
// use stream APIs on Windows Server 2003 and newer
|
|
||||||
if (file.getFileSystem().supportsStreamEnumeration()) {
|
|
||||||
return listUsingStreamEnumeration();
|
return listUsingStreamEnumeration();
|
||||||
} else {
|
|
||||||
return listUsingBackupRead();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,10 +69,6 @@ static jfieldID completionStatus_error;
|
|||||||
static jfieldID completionStatus_bytesTransferred;
|
static jfieldID completionStatus_bytesTransferred;
|
||||||
static jfieldID completionStatus_completionKey;
|
static jfieldID completionStatus_completionKey;
|
||||||
|
|
||||||
static jfieldID backupResult_bytesTransferred;
|
|
||||||
static jfieldID backupResult_context;
|
|
||||||
|
|
||||||
|
|
||||||
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
|
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
|
||||||
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
|
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
|
||||||
"(I)V", lastError);
|
"(I)V", lastError);
|
||||||
@ -148,13 +144,6 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
|
|||||||
CHECK_NULL(completionStatus_bytesTransferred);
|
CHECK_NULL(completionStatus_bytesTransferred);
|
||||||
completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J");
|
completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J");
|
||||||
CHECK_NULL(completionStatus_completionKey);
|
CHECK_NULL(completionStatus_completionKey);
|
||||||
|
|
||||||
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$BackupResult");
|
|
||||||
CHECK_NULL(clazz);
|
|
||||||
backupResult_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
|
|
||||||
CHECK_NULL(backupResult_bytesTransferred);
|
|
||||||
backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
|
|
||||||
CHECK_NULL(backupResult_context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
@ -1228,52 +1217,3 @@ Java_sun_nio_fs_WindowsNativeDispatcher_ReadDirectoryChangesW(JNIEnv* env, jclas
|
|||||||
throwWindowsException(env, GetLastError());
|
throwWindowsException(env, GetLastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_sun_nio_fs_WindowsNativeDispatcher_BackupRead0(JNIEnv* env, jclass this,
|
|
||||||
jlong hFile, jlong bufferAddress, jint bufferSize, jboolean abort,
|
|
||||||
jlong context, jobject obj)
|
|
||||||
{
|
|
||||||
BOOL res;
|
|
||||||
DWORD bytesTransferred;
|
|
||||||
BOOL a = (abort == JNI_TRUE) ? TRUE : FALSE;
|
|
||||||
VOID* pContext = (VOID*)jlong_to_ptr(context);
|
|
||||||
|
|
||||||
res = BackupRead((HANDLE)jlong_to_ptr(hFile),
|
|
||||||
(LPBYTE)jlong_to_ptr(bufferAddress),
|
|
||||||
(DWORD)bufferSize,
|
|
||||||
&bytesTransferred,
|
|
||||||
a,
|
|
||||||
FALSE,
|
|
||||||
&pContext);
|
|
||||||
if (res == 0) {
|
|
||||||
throwWindowsException(env, GetLastError());
|
|
||||||
} else {
|
|
||||||
(*env)->SetIntField(env, obj, backupResult_bytesTransferred,
|
|
||||||
bytesTransferred);
|
|
||||||
(*env)->SetLongField(env, obj, backupResult_context,
|
|
||||||
ptr_to_jlong(pContext));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_sun_nio_fs_WindowsNativeDispatcher_BackupSeek(JNIEnv* env, jclass this,
|
|
||||||
jlong hFile, jlong bytesToSeek, jlong context)
|
|
||||||
{
|
|
||||||
BOOL res;
|
|
||||||
jint lowBytesToSeek = (jint)bytesToSeek;
|
|
||||||
jint highBytesToSeek = (jint)(bytesToSeek >> 32);
|
|
||||||
DWORD lowBytesSeeked;
|
|
||||||
DWORD highBytesSeeked;
|
|
||||||
VOID* pContext = jlong_to_ptr(context);
|
|
||||||
|
|
||||||
res = BackupSeek((HANDLE)jlong_to_ptr(hFile),
|
|
||||||
(DWORD)lowBytesToSeek,
|
|
||||||
(DWORD)highBytesToSeek,
|
|
||||||
&lowBytesSeeked,
|
|
||||||
&highBytesSeeked,
|
|
||||||
&pContext);
|
|
||||||
if (res == 0) {
|
|
||||||
throwWindowsException(env, GetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user