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;
|
||||
try {
|
||||
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
if (!followLinks && file.getFileSystem().supportsLinks())
|
||||
if (!followLinks)
|
||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
|
||||
handle = CreateFile(file.getPathForWin32Calls(),
|
||||
|
@ -168,9 +168,7 @@ class WindowsFileCopy {
|
||||
|
||||
// Use CopyFileEx if the file is not a directory or junction
|
||||
if (!sourceAttrs.isDirectory() && !sourceAttrs.isDirectoryLink()) {
|
||||
final int flags =
|
||||
(source.getFileSystem().supportsLinks() && !followLinks) ?
|
||||
COPY_FILE_COPY_SYMLINK : 0;
|
||||
final int flags = (!followLinks) ? COPY_FILE_COPY_SYMLINK : 0;
|
||||
|
||||
if (interruptible) {
|
||||
// interruptible copy
|
||||
|
@ -78,14 +78,7 @@ class WindowsFileStore
|
||||
// if the file is a link then GetVolumePathName returns the
|
||||
// volume that the link is on so we need to call it with the
|
||||
// final target
|
||||
String target;
|
||||
if (file.getFileSystem().supportsLinks()) {
|
||||
target = WindowsLinkSupport.getFinalPath(file, true);
|
||||
} else {
|
||||
// file must exist
|
||||
WindowsFileAttributes.get(file, true);
|
||||
target = file.getPathForWin32Calls();
|
||||
}
|
||||
String target = WindowsLinkSupport.getFinalPath(file, true);
|
||||
try {
|
||||
return createFromPath(target);
|
||||
} catch (WindowsException e) {
|
||||
|
@ -31,9 +31,6 @@ import java.nio.file.spi.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
class WindowsFileSystem
|
||||
extends FileSystem
|
||||
@ -44,9 +41,6 @@ class WindowsFileSystem
|
||||
private final String defaultDirectory;
|
||||
private final String defaultRoot;
|
||||
|
||||
private final boolean supportsLinks;
|
||||
private final boolean supportsStreamEnumeration;
|
||||
|
||||
// package-private
|
||||
WindowsFileSystem(WindowsFileSystemProvider provider,
|
||||
String dir)
|
||||
@ -61,18 +55,6 @@ class WindowsFileSystem
|
||||
throw new AssertionError("Default directory is not an absolute path");
|
||||
this.defaultDirectory = result.path();
|
||||
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
|
||||
@ -84,14 +66,6 @@ class WindowsFileSystem
|
||||
return defaultRoot;
|
||||
}
|
||||
|
||||
boolean supportsLinks() {
|
||||
return supportsLinks;
|
||||
}
|
||||
|
||||
boolean supportsStreamEnumeration() {
|
||||
return supportsStreamEnumeration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSystemProvider provider() {
|
||||
return provider;
|
||||
|
@ -526,11 +526,6 @@ public class WindowsFileSystemProvider
|
||||
WindowsPath link = WindowsPath.toWindowsPath(obj1);
|
||||
WindowsPath target = WindowsPath.toWindowsPath(obj2);
|
||||
|
||||
if (!link.getFileSystem().supportsLinks()) {
|
||||
throw new UnsupportedOperationException("Symbolic links not supported "
|
||||
+ "on this operating system");
|
||||
}
|
||||
|
||||
// no attributes allowed
|
||||
if (attrs.length > 0) {
|
||||
WindowsSecurityDescriptor.fromAttribute(attrs); // may throw NPE or UOE
|
||||
@ -614,9 +609,6 @@ public class WindowsFileSystemProvider
|
||||
public Path readSymbolicLink(Path obj1) throws IOException {
|
||||
WindowsPath link = WindowsPath.toWindowsPath(obj1);
|
||||
WindowsFileSystem fs = link.getFileSystem();
|
||||
if (!fs.supportsLinks()) {
|
||||
throw new UnsupportedOperationException("symbolic links not supported");
|
||||
}
|
||||
|
||||
// permission check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
|
@ -96,7 +96,7 @@ class WindowsLinkSupport {
|
||||
WindowsFileSystem fs = input.getFileSystem();
|
||||
try {
|
||||
// if not following links then don't need final path
|
||||
if (!followLinks || !fs.supportsLinks())
|
||||
if (!followLinks)
|
||||
return input.getPathForWin32Calls();
|
||||
|
||||
// if file is not a sym link then don't need final path
|
||||
@ -157,8 +157,6 @@ class WindowsLinkSupport {
|
||||
throws IOException
|
||||
{
|
||||
WindowsFileSystem fs = input.getFileSystem();
|
||||
if (resolveLinks && !fs.supportsLinks())
|
||||
resolveLinks = false;
|
||||
|
||||
// Start with absolute path
|
||||
String path = null;
|
||||
|
@ -1071,54 +1071,6 @@ class WindowsNativeDispatcher {
|
||||
static native int GetOverlappedResult(long hFile, long lpOverlapped)
|
||||
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 --
|
||||
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
@ -780,7 +780,7 @@ class WindowsPath implements Path {
|
||||
throws WindowsException
|
||||
{
|
||||
int flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
if (!followLinks && getFileSystem().supportsLinks())
|
||||
if (!followLinks)
|
||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
return CreateFile(getPathForWin32Calls(),
|
||||
FILE_READ_ATTRIBUTES,
|
||||
|
@ -91,121 +91,11 @@ class WindowsUserDefinedFileAttributeView
|
||||
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
|
||||
public List<String> list() throws IOException {
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), true, false);
|
||||
// use stream APIs on Windows Server 2003 and newer
|
||||
if (file.getFileSystem().supportsStreamEnumeration()) {
|
||||
return listUsingStreamEnumeration();
|
||||
} else {
|
||||
return listUsingBackupRead();
|
||||
}
|
||||
return listUsingStreamEnumeration();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,10 +69,6 @@ static jfieldID completionStatus_error;
|
||||
static jfieldID completionStatus_bytesTransferred;
|
||||
static jfieldID completionStatus_completionKey;
|
||||
|
||||
static jfieldID backupResult_bytesTransferred;
|
||||
static jfieldID backupResult_context;
|
||||
|
||||
|
||||
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
|
||||
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
|
||||
"(I)V", lastError);
|
||||
@ -148,13 +144,6 @@ 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);
|
||||
|
||||
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
|
||||
@ -1228,52 +1217,3 @@ Java_sun_nio_fs_WindowsNativeDispatcher_ReadDirectoryChangesW(JNIEnv* env, jclas
|
||||
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…
Reference in New Issue
Block a user