--- a/src/hotspot/os/windows/os_windows.cpp Fri Jun 28 18:01:36 2019 +0200
+++ b/src/hotspot/os/windows/os_windows.cpp Fri Jun 28 09:49:10 2019 -0700
@@ -4367,6 +4367,88 @@
return ret;
}
+static HANDLE create_read_only_file_handle(const char* file) {
+ if (file == NULL) {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ char* nativepath = (char*)os::strdup(file, mtInternal);
+ if (nativepath == NULL) {
+ errno = ENOMEM;
+ return INVALID_HANDLE_VALUE;
+ }
+ os::native_path(nativepath);
+
+ size_t len = strlen(nativepath);
+ HANDLE handle = INVALID_HANDLE_VALUE;
+
+ if (len < MAX_PATH) {
+ handle = ::CreateFile(nativepath, 0, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ } else {
+ errno_t err = ERROR_SUCCESS;
+ wchar_t* wfile = create_unc_path(nativepath, err);
+ if (err != ERROR_SUCCESS) {
+ if (wfile != NULL) {
+ destroy_unc_path(wfile);
+ }
+ os::free(nativepath);
+ return INVALID_HANDLE_VALUE;
+ }
+ handle = ::CreateFileW(wfile, 0, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ destroy_unc_path(wfile);
+ }
+
+ os::free(nativepath);
+ return handle;
+}
+
+bool os::same_files(const char* file1, const char* file2) {
+
+ if (file1 == NULL && file2 == NULL) {
+ return true;
+ }
+
+ if (file1 == NULL || file2 == NULL) {
+ return false;
+ }
+
+ if (strcmp(file1, file2) == 0) {
+ return true;
+ }
+
+ HANDLE handle1 = create_read_only_file_handle(file1);
+ HANDLE handle2 = create_read_only_file_handle(file2);
+ bool result = false;
+
+ // if we could open both paths...
+ if (handle1 != INVALID_HANDLE_VALUE && handle2 != INVALID_HANDLE_VALUE) {
+ BY_HANDLE_FILE_INFORMATION fileInfo1;
+ BY_HANDLE_FILE_INFORMATION fileInfo2;
+ if (::GetFileInformationByHandle(handle1, &fileInfo1) &&
+ ::GetFileInformationByHandle(handle2, &fileInfo2)) {
+ // the paths are the same if they refer to the same file (fileindex) on the same volume (volume serial number)
+ if (fileInfo1.dwVolumeSerialNumber == fileInfo2.dwVolumeSerialNumber &&
+ fileInfo1.nFileIndexHigh == fileInfo2.nFileIndexHigh &&
+ fileInfo1.nFileIndexLow == fileInfo2.nFileIndexLow) {
+ result = true;
+ }
+ }
+ }
+
+ //free the handles
+ if (handle1 != INVALID_HANDLE_VALUE) {
+ ::CloseHandle(handle1);
+ }
+
+ if (handle2 != INVALID_HANDLE_VALUE) {
+ ::CloseHandle(handle2);
+ }
+
+ return result;
+}
+
#define FT2INT64(ft) \
((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))