< prev index next >
src/hotspot/os/windows/os_windows.cpp
Print this page
*** 4164,4193 ****
// Returns the given path as an absolute wide path in unc format. The returned path is NULL
// on error (with err being set accordingly) and should be freed via os::free() otherwise.
// additional_space is the number of additionally allocated wchars after the terminating L'\0'.
// This is based on pathToNTPath() in io_util_md.cpp, but omits the optimizations for
// short paths.
! static wchar_t* wide_abs_unc_path(char const* path, errno_t & err, int additional_space = 0) {
if ((path == NULL) || (path[0] == '\0')) {
err = ENOENT;
return NULL;
}
- size_t path_len = strlen(path);
// Need to allocate at least room for 3 characters, since os::native_path transforms C: to C:.
! char* buf = (char*) os::malloc(1 + MAX2((size_t) 3, path_len), mtInternal);
! wchar_t* result = NULL;
!
if (buf == NULL) {
err = ENOMEM;
! } else {
! memcpy(buf, path, path_len + 1);
os::native_path(buf);
! wchar_t* prefix;
int prefix_off = 0;
- bool is_abs = true;
bool needs_fullpath = true;
if (::isalpha(buf[0]) && !::IsDBCSLeadByte(buf[0]) && buf[1] == ':' && buf[2] == '\\') {
prefix = L"\\\\?\\";
} else if (buf[0] == '\\' && buf[1] == '\\') {
--- 4164,4202 ----
// Returns the given path as an absolute wide path in unc format. The returned path is NULL
// on error (with err being set accordingly) and should be freed via os::free() otherwise.
// additional_space is the number of additionally allocated wchars after the terminating L'\0'.
// This is based on pathToNTPath() in io_util_md.cpp, but omits the optimizations for
// short paths.
! static LPWSTR wide_abs_unc_path(char const* path, errno_t & err, int additional_space = 0) {
if ((path == NULL) || (path[0] == '\0')) {
err = ENOENT;
return NULL;
}
// Need to allocate at least room for 3 characters, since os::native_path transforms C: to C:.
! size_t buf_size = 1 + MAX2((size_t)3, strlen(path));
! char* buf = static_cast<char*>(os::malloc(buf_size, mtInternal));
if (buf == NULL) {
err = ENOMEM;
! return NULL;
! }
! memcpy(buf, path, buf_size);
os::native_path(buf);
! // Get required buffer size to convert to Unicode
! int unicode_path_len = MultiByteToWideChar(CP_THREAD_ACP,
! MB_ERR_INVALID_CHARS,
! buf, -1,
! NULL, 0);
! if (unicode_path_len == 0) {
! os::free(buf);
! err = EINVAL;
! return NULL;
! }
!
! LPWSTR prefix;
int prefix_off = 0;
bool needs_fullpath = true;
if (::isalpha(buf[0]) && !::IsDBCSLeadByte(buf[0]) && buf[1] == ':' && buf[2] == '\\') {
prefix = L"\\\\?\\";
} else if (buf[0] == '\\' && buf[1] == '\\') {
*** 4197,4252 ****
} else {
prefix = L"\\\\?\\UNC";
prefix_off = 1; // Overwrite the first char with the prefix, so \\share\path becomes \\?\UNC\share\path
}
} else {
- is_abs = false;
prefix = L"\\\\?\\";
}
-
- size_t buf_len = strlen(buf);
size_t prefix_len = wcslen(prefix);
! size_t full_path_size = is_abs ? 1 + buf_len : JVM_MAXPATHLEN;
! size_t result_size = prefix_len + full_path_size - prefix_off;
! result = (wchar_t*) os::malloc(sizeof(wchar_t) * (additional_space + result_size), mtInternal);
! if (result == NULL) {
err = ENOMEM;
} else {
! size_t converted_chars;
! wchar_t* path_start = result + prefix_len - prefix_off;
! err = ::mbstowcs_s(&converted_chars, path_start, buf_len + 1, buf, buf_len);
!
! if ((err == ERROR_SUCCESS) && needs_fullpath) {
! wchar_t* tmp = (wchar_t*) os::malloc(sizeof(wchar_t) * full_path_size, mtInternal);
!
! if (tmp == NULL) {
! err = ENOMEM;
} else {
! if (!_wfullpath(tmp, path_start, full_path_size)) {
! err = ENOENT;
} else {
! ::memcpy(path_start, tmp, (1 + wcslen(tmp)) * sizeof(wchar_t));
}
!
! os::free(tmp);
}
}
- memcpy(result, prefix, sizeof(wchar_t) * prefix_len);
-
// Remove trailing pathsep (not for \\?\<DRIVE>:\, since it would make it relative)
! size_t result_len = wcslen(result);
if (result[result_len - 1] == L'\\') {
if (!(::iswalpha(result[4]) && result[5] == L':' && result_len == 7)) {
result[result_len - 1] = L'\0';
}
}
}
- }
os::free(buf);
if (err != ERROR_SUCCESS) {
os::free(result);
result = NULL;
--- 4206,4273 ----
} else {
prefix = L"\\\\?\\UNC";
prefix_off = 1; // Overwrite the first char with the prefix, so \\share\path becomes \\?\UNC\share\path
}
} else {
prefix = L"\\\\?\\";
}
size_t prefix_len = wcslen(prefix);
! LPWSTR result = NULL;
! LPWSTR unicode_path = static_cast<LPWSTR>(os::malloc(sizeof(WCHAR) * unicode_path_len, mtInternal));
! if (unicode_path == NULL) {
err = ENOMEM;
} else {
! // This call would be success because it is checked in above
! err = ERROR_SUCCESS;
! MultiByteToWideChar(CP_THREAD_ACP,
! MB_ERR_INVALID_CHARS,
! buf, -1,
! unicode_path, unicode_path_len);
!
! size_t result_len = prefix_len + prefix_off + additional_space;
! if (needs_fullpath) {
! // Get required buffer size to convert to full path
! DWORD full_path_len = GetFullPathNameW(unicode_path, 0, NULL, NULL);
! if (full_path_len == 0) {
! err = EINVAL;
} else {
! size_t result_size = sizeof(WCHAR) * (result_len + full_path_len);
! result = static_cast<LPWSTR>(os::malloc(result_size, mtInternal));
! if (result == NULL) {
! err = ENOMEM;
} else {
! // Copy prefix
! memcpy(result, prefix, sizeof(WCHAR) * prefix_len);
! // This call would be success because it is checked in above
! GetFullPathNameW(unicode_path, full_path_len, result + prefix_len - prefix_off, NULL);
}
! }
! } else {
! size_t result_size = sizeof(WCHAR) * (result_len + unicode_path_len);
! result = static_cast<LPWSTR>(os::malloc(result_size, mtInternal));
! if (result == NULL) {
! err = ENOMEM;
! } else {
! // Copy prefix
! memcpy(result, prefix, sizeof(WCHAR) * prefix_len);
! // Copy unicode path
! memcpy(result + prefix_len - prefix_off, unicode_path, sizeof(WCHAR) * unicode_path_len);
}
}
// Remove trailing pathsep (not for \\?\<DRIVE>:\, since it would make it relative)
! result_len = wcslen(result);
if (result[result_len - 1] == L'\\') {
if (!(::iswalpha(result[4]) && result[5] == L':' && result_len == 7)) {
result[result_len - 1] = L'\0';
}
}
}
+ os::free(unicode_path);
os::free(buf);
if (err != ERROR_SUCCESS) {
os::free(result);
result = NULL;
< prev index next >