diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 61df19753ef..eec3d86590f 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -822,6 +822,31 @@ fs::equivalent(const path& p1, const path& p2)
   return result;
 }

+#if _GLIBCXX_FILESYSTEM_IS_WINDOWS
+namespace
+{
+  struct auto_win_file_handle {
+      explicit auto_win_file_handle(const fs::path& p_)
+        : handle(CreateFileW(p_.c_str(), 0,
+                             FILE_SHARE_DELETE | FILE_SHARE_READ |
FILE_SHARE_WRITE,
+                             0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0))
+      { }
+
+      ~auto_win_file_handle()
+        { if (*this) CloseHandle(handle); }
+
+      explicit operator bool() const
+        { return handle != INVALID_HANDLE_VALUE; }
+
+      bool get_info()
+        { return GetFileInformationByHandle(handle, &info); }
+
+      HANDLE handle;
+      BY_HANDLE_FILE_INFORMATION info;
+  };
+}
+#endif
+
 bool
 fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept
 {
@@ -858,27 +883,8 @@ fs::equivalent(const path& p1, const path& p2,
error_code& ec) noexcept
       if (st1.st_mode != st2.st_mode || st1.st_dev != st2.st_dev)
  return false;

-      struct auto_handle {
- explicit auto_handle(const path& p_)
- : handle(CreateFileW(p_.c_str(), 0,
-       FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
-       0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0))
- { }
-
- ~auto_handle()
- { if (*this) CloseHandle(handle); }
-
- explicit operator bool() const
- { return handle != INVALID_HANDLE_VALUE; }
-
- bool get_info()
- { return GetFileInformationByHandle(handle, &info); }
-
- HANDLE handle;
- BY_HANDLE_FILE_INFORMATION info;
-      };
-      auto_handle h1(p1);
-      auto_handle h2(p2);
+      auto_win_file_handle h1(p1);
+      auto_win_file_handle h2(p2);
       if (!h1 || !h2)
  {
    if (!h1 && !h2)
@@ -982,7 +988,16 @@ fs::hard_link_count(const path& p)
 std::uintmax_t
 fs::hard_link_count(const path& p, error_code& ec) noexcept
 {
-#ifdef _GLIBCXX_HAVE_SYS_STAT_H
+#if _GLIBCXX_FILESYSTEM_IS_WINDOWS
+  auto_win_file_handle h(p);
+  if (h && h.get_info())
+    {
+      return static_cast<uintmax_t>(h.info.nNumberOfLinks);
+    }
+
+  ec = __last_system_error();
+  return static_cast<uintmax_t>(-1);
+#elif defined(_GLIBCXX_HAVE_SYS_STAT_H)
   return do_stat(p, ec, std::mem_fn(&stat_type::st_nlink),
  static_cast<uintmax_t>(-1));
 #else
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/hard_link_count.cc
b/libstdc++-v3/testsuite/27_io/filesystem/operations/hard_link_count.cc
new file mode 100644
index 00000000000..5acba96aa82
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/hard_link_count.cc
@@ -0,0 +1,54 @@
+// Copyright (C) 2019-2024 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++17 } }
+// { dg-require-filesystem-ts "" }
+
+#include <filesystem>
+#include <testsuite_hooks.h>
+#include <testsuite_fs.h>
+
+namespace fs = std::filesystem;
+
+void test01()
+{
+  // PR libstdc++/113663
+
+  fs::path p1 = __gnu_test::nonexistent_path();
+  VERIFY( !fs::exists(p1) );
+
+  __gnu_test::scoped_file f1(p1);
+  VERIFY( fs::exists(p1) );
+
+  VERIFY( fs::hard_link_count(p1) == 1 );
+
+  fs::path p2 = __gnu_test::nonexistent_path();
+  VERIFY( !fs::exists(p2) );
+
+  fs::create_hard_link(p1, p2);
+  __gnu_test::scoped_file f2(p2, __gnu_test::scoped_file::adopt_file);
+  VERIFY( fs::exists(p2) );
+
+  VERIFY( fs::hard_link_count(p1) == 2 );
+  VERIFY( fs::hard_link_count(p2) == 2 );
+}
+
+int
+main()
+{
+  test01();
+}
