瀏覽代碼

Merge pull request #74830 from AThousandShips/win_time_fix

[Windows] Use `GetFileTime` for `FileAccess`
Rémi Verschelde 1 年之前
父節點
當前提交
88e9af6b7c
共有 1 個文件被更改,包括 32 次插入7 次删除
  1. 32 7
      drivers/windows/file_access_windows.cpp

+ 32 - 7
drivers/windows/file_access_windows.cpp

@@ -412,15 +412,40 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
 		file = file.substr(0, file.length() - 1);
 	}
 
-	struct _stat st;
-	int rv = _wstat((LPCWSTR)(file.utf16().get_data()), &st);
+	HANDLE handle = CreateFileW((LPCWSTR)(file.utf16().get_data()), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
 
-	if (rv == 0) {
-		return st.st_mtime;
-	} else {
-		print_verbose("Failed to get modified time for: " + p_file + "");
-		return 0;
+	if (handle != INVALID_HANDLE_VALUE) {
+		FILETIME ft_create, ft_write;
+
+		bool status = GetFileTime(handle, &ft_create, nullptr, &ft_write);
+
+		CloseHandle(handle);
+
+		if (status) {
+			uint64_t ret = 0;
+
+			// If write time is invalid, fallback to creation time.
+			if (ft_write.dwHighDateTime == 0 && ft_write.dwLowDateTime == 0) {
+				ret = ft_create.dwHighDateTime;
+				ret <<= 32;
+				ret |= ft_create.dwLowDateTime;
+			} else {
+				ret = ft_write.dwHighDateTime;
+				ret <<= 32;
+				ret |= ft_write.dwLowDateTime;
+			}
+
+			const uint64_t WINDOWS_TICKS_PER_SECOND = 10000000;
+			const uint64_t TICKS_TO_UNIX_EPOCH = 116444736000000000LL;
+
+			if (ret >= TICKS_TO_UNIX_EPOCH) {
+				return (ret - TICKS_TO_UNIX_EPOCH) / WINDOWS_TICKS_PER_SECOND;
+			}
+		}
 	}
+
+	print_verbose("Failed to get modified time for: " + p_file);
+	return 0;
 }
 
 BitField<FileAccess::UnixPermissionFlags> FileAccessWindows::_get_unix_permissions(const String &p_file) {