mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8003887: File.getCanonicalFile() does not resolve symlinks on MS Windows
Reviewed-by: alanb
This commit is contained in:
parent
b389bb4567
commit
042053c3a8
3 changed files with 127 additions and 26 deletions
|
@ -490,12 +490,26 @@ final class WinNTFileSystem extends FileSystem {
|
|||
return path;
|
||||
return "" + ((char) (c-32)) + ':' + '\\';
|
||||
}
|
||||
return canonicalize0(path);
|
||||
String canonicalPath = canonicalize0(path);
|
||||
String finalPath = null;
|
||||
try {
|
||||
finalPath = getFinalPath(canonicalPath);
|
||||
} catch (IOException ignored) {
|
||||
finalPath = canonicalPath;
|
||||
}
|
||||
return finalPath;
|
||||
}
|
||||
|
||||
private native String canonicalize0(String path)
|
||||
throws IOException;
|
||||
|
||||
private String getFinalPath(String path) throws IOException {
|
||||
return getFinalPath0(path);
|
||||
}
|
||||
|
||||
private native String getFinalPath0(String path)
|
||||
throws IOException;
|
||||
|
||||
|
||||
/* -- Attribute accessors -- */
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2024, 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
|
||||
|
@ -46,31 +46,15 @@ static struct {
|
|||
jfieldID path;
|
||||
} ids;
|
||||
|
||||
/**
|
||||
* GetFinalPathNameByHandle is available on Windows Vista and newer
|
||||
*/
|
||||
typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD);
|
||||
static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func;
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_java_io_WinNTFileSystem_initIDs(JNIEnv *env, jclass cls)
|
||||
{
|
||||
HMODULE handle;
|
||||
jclass fileClass;
|
||||
|
||||
fileClass = (*env)->FindClass(env, "java/io/File");
|
||||
CHECK_NULL(fileClass);
|
||||
ids.path = (*env)->GetFieldID(env, fileClass, "path", "Ljava/lang/String;");
|
||||
CHECK_NULL(ids.path);
|
||||
|
||||
// GetFinalPathNameByHandle requires Windows Vista or newer
|
||||
if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
|
||||
(LPCWSTR)&CreateFileW, &handle) != 0)
|
||||
{
|
||||
GetFinalPathNameByHandle_func = (GetFinalPathNameByHandleProc)
|
||||
GetProcAddress(handle, "GetFinalPathNameByHandleW");
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Path operations -- */
|
||||
|
@ -88,10 +72,6 @@ static WCHAR* getFinalPath(JNIEnv *env, const WCHAR *path)
|
|||
WCHAR *result;
|
||||
DWORD error;
|
||||
|
||||
/* Need Windows Vista or newer to get the final path */
|
||||
if (GetFinalPathNameByHandle_func == NULL)
|
||||
return NULL;
|
||||
|
||||
h = CreateFileW(path,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
FILE_SHARE_DELETE |
|
||||
|
@ -109,13 +89,13 @@ static WCHAR* getFinalPath(JNIEnv *env, const WCHAR *path)
|
|||
*/
|
||||
result = (WCHAR*)malloc(MAX_PATH * sizeof(WCHAR));
|
||||
if (result != NULL) {
|
||||
DWORD len = (*GetFinalPathNameByHandle_func)(h, result, MAX_PATH, 0);
|
||||
DWORD len = GetFinalPathNameByHandleW(h, result, MAX_PATH, 0);
|
||||
if (len >= MAX_PATH) {
|
||||
/* retry with a buffer of the right size */
|
||||
WCHAR* newResult = (WCHAR*)realloc(result, (len+1) * sizeof(WCHAR));
|
||||
if (newResult != NULL) {
|
||||
result = newResult;
|
||||
len = (*GetFinalPathNameByHandle_func)(h, result, len, 0);
|
||||
len = GetFinalPathNameByHandleW(h, result, len, 0);
|
||||
} else {
|
||||
len = 0;
|
||||
JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
|
||||
|
@ -351,6 +331,25 @@ Java_java_io_WinNTFileSystem_canonicalizeWithPrefix0(JNIEnv *env, jobject this,
|
|||
return rv;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_java_io_WinNTFileSystem_getFinalPath0(JNIEnv* env, jobject this, jstring pathname) {
|
||||
jstring rv = NULL;
|
||||
|
||||
WITH_UNICODE_STRING(env, pathname, path) {
|
||||
WCHAR* finalPath = getFinalPath(env, path);
|
||||
if (finalPath != NULL) {
|
||||
rv = (*env)->NewString(env, finalPath, (jsize)wcslen(finalPath));
|
||||
free(finalPath);
|
||||
}
|
||||
} END_UNICODE_STRING(env, path);
|
||||
|
||||
if (rv == NULL && !(*env)->ExceptionCheck(env)) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* -- Attribute accessors -- */
|
||||
|
||||
/* Check whether or not the file name in "path" is a Windows reserved
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue