Adding WinUWP compilation support to WebRTC.

Windows UWP allows an application to be built that targets
across all Windows 10 based systems and the Windows store.

Change-Id: I69694bb7e83fb01ad6db2438b065b55738cf01fd
Bug: webrtc:10046
Reviewed-on: https://webrtc-review.googlesource.com/c/110570
Commit-Queue: Patrik Höglund <phoglund@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25814}
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index 4ed07af..d87d5d6 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -47,12 +47,14 @@
 
   if (is_linux || is_win) {
     deps += [
-      ":peerconnection_client",
       ":peerconnection_server",
       ":relayserver",
       ":stunserver",
       ":turnserver",
     ]
+    if (current_os != "winuwp") {
+      deps += [ ":peerconnection_client" ]
+    }
   }
 
   if (is_android || is_win) {
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 75c4397..c88815f 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -870,11 +870,13 @@
     ]
 
     if (is_win) {
-      sources += [
-        "win32socketinit.h",
-        "win32socketserver.cc",
-        "win32socketserver.h",
-      ]
+      sources += [ "win32socketinit.h" ]
+      if (current_os != "winuwp") {
+        sources += [
+          "win32socketserver.cc",
+          "win32socketserver.h",
+        ]
+      }
     }
   }  # !build_with_chromium
 
diff --git a/rtc_base/httpcommon.cc b/rtc_base/httpcommon.cc
index 7926f88..4fa5f41 100644
--- a/rtc_base/httpcommon.cc
+++ b/rtc_base/httpcommon.cc
@@ -38,7 +38,7 @@
 
 namespace rtc {
 namespace {
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
 ///////////////////////////////////////////////////////////////////////////////
 // ConstantToLabel can be used to easily generate string names from constant
 // values.  This can be useful for logging descriptive names of error messages.
@@ -113,7 +113,7 @@
     LASTLABEL};
 #undef KLABEL
 #undef LASTLABEL
-#endif  // defined(WEBRTC_WIN)
+#endif  // defined(WEBRTC_WIN) && !defined(WINUWP)
 
 typedef std::pair<std::string, std::string> HttpAttribute;
 typedef std::vector<HttpAttribute> HttpAttributeList;
@@ -225,7 +225,7 @@
   return result;
 }
 
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
 struct NegotiateAuthContext : public HttpAuthContext {
   CredHandle cred;
   CtxtHandle ctx;
@@ -244,7 +244,7 @@
     FreeCredentialsHandle(&cred);
   }
 };
-#endif  // WEBRTC_WIN
+#endif  // defined(WEBRTC_WIN) && !defined(WINUWP)
 
 }  // anonymous namespace
 
@@ -359,7 +359,7 @@
     return HAR_RESPONSE;
   }
 
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
 #if 1
   bool want_negotiate = absl::EqualsIgnoreCase(auth_method, "negotiate");
   bool want_ntlm = absl::EqualsIgnoreCase(auth_method, "ntlm");
@@ -544,7 +544,7 @@
     return HAR_RESPONSE;
   }
 #endif
-#endif  // WEBRTC_WIN
+#endif  // defined(WEBRTC_WIN) && !defined(WINUWP)
 
   return HAR_IGNORE;
 }
diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc
index bb4fbfa..8d6afbc 100644
--- a/rtc_base/logging.cc
+++ b/rtc_base/logging.cc
@@ -327,7 +327,7 @@
     }
   }
 
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
   if ((LS_NONE != debug_level) && !::IsDebuggerPresent()) {
     // First, attempt to attach to our parent's console... so if you invoke
     // from the command line, we'll see the output there.  Otherwise, create
@@ -336,7 +336,7 @@
     if (!AttachConsole(ATTACH_PARENT_PROCESS))
       ::AllocConsole();
   }
-#endif  // WEBRTC_WIN
+#endif  // defined(WEBRTC_WIN) && !defined(WINUWP)
 
   LogToDebug(debug_level);
 }
diff --git a/rtc_base/nethelpers.cc b/rtc_base/nethelpers.cc
index 81cd1af..1bba3b4 100644
--- a/rtc_base/nethelpers.cc
+++ b/rtc_base/nethelpers.cc
@@ -161,7 +161,10 @@
 }
 
 bool HasIPv6Enabled() {
-#if defined(WEBRTC_WIN)
+#if defined(WINUWP)
+  // WinUWP always has IPv6 capability.
+  return true;
+#elif defined(WEBRTC_WIN)
   if (IsWindowsVistaOrLater()) {
     return true;
   }
diff --git a/rtc_base/socketadapters.cc b/rtc_base/socketadapters.cc
index 9451928..3bac17b 100644
--- a/rtc_base/socketadapters.cc
+++ b/rtc_base/socketadapters.cc
@@ -427,7 +427,7 @@
         // std::string msg("Please report the following information to
         // foo@bar.com:\r\nUnknown methods: ");
         msg.append(unknown_mechanisms_);
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
         MessageBoxA(0, msg.c_str(), "Oops!", MB_OK);
 #endif
 #if defined(WEBRTC_POSIX)
diff --git a/rtc_base/synchronization/rw_lock_win.cc b/rtc_base/synchronization/rw_lock_win.cc
index 44cc0a7..a0d24a3 100644
--- a/rtc_base/synchronization/rw_lock_win.cc
+++ b/rtc_base/synchronization/rw_lock_win.cc
@@ -14,23 +14,19 @@
 
 namespace webrtc {
 
-static bool native_rw_locks_supported = false;
-static bool module_load_attempted = false;
-static HMODULE library = NULL;
+typedef void(WINAPI* PInitializeSRWLock)(PSRWLOCK);
 
-typedef void(WINAPI* InitializeSRWLock)(PSRWLOCK);
+typedef void(WINAPI* PAcquireSRWLockExclusive)(PSRWLOCK);
+typedef void(WINAPI* PReleaseSRWLockExclusive)(PSRWLOCK);
 
-typedef void(WINAPI* AcquireSRWLockExclusive)(PSRWLOCK);
-typedef void(WINAPI* ReleaseSRWLockExclusive)(PSRWLOCK);
+typedef void(WINAPI* PAcquireSRWLockShared)(PSRWLOCK);
+typedef void(WINAPI* PReleaseSRWLockShared)(PSRWLOCK);
 
-typedef void(WINAPI* AcquireSRWLockShared)(PSRWLOCK);
-typedef void(WINAPI* ReleaseSRWLockShared)(PSRWLOCK);
-
-InitializeSRWLock initialize_srw_lock;
-AcquireSRWLockExclusive acquire_srw_lock_exclusive;
-AcquireSRWLockShared acquire_srw_lock_shared;
-ReleaseSRWLockShared release_srw_lock_shared;
-ReleaseSRWLockExclusive release_srw_lock_exclusive;
+PInitializeSRWLock initialize_srw_lock;
+PAcquireSRWLockExclusive acquire_srw_lock_exclusive;
+PAcquireSRWLockShared acquire_srw_lock_shared;
+PReleaseSRWLockShared release_srw_lock_shared;
+PReleaseSRWLockExclusive release_srw_lock_exclusive;
 
 RWLockWin::RWLockWin() {
   initialize_srw_lock(&lock_);
@@ -60,28 +56,31 @@
 }
 
 bool RWLockWin::LoadModule() {
+  static bool module_load_attempted = false;
+  static bool native_rw_locks_supported = false;
   if (module_load_attempted) {
     return native_rw_locks_supported;
   }
   module_load_attempted = true;
+#if !defined(WINUWP)
   // Use native implementation if supported (i.e Vista+)
-  library = LoadLibrary(TEXT("Kernel32.dll"));
+  static HMODULE library = LoadLibrary(TEXT("Kernel32.dll"));
   if (!library) {
     return false;
   }
   RTC_LOG(LS_VERBOSE) << "Loaded Kernel.dll";
 
   initialize_srw_lock =
-      (InitializeSRWLock)GetProcAddress(library, "InitializeSRWLock");
+      (PInitializeSRWLock)GetProcAddress(library, "InitializeSRWLock");
 
-  acquire_srw_lock_exclusive = (AcquireSRWLockExclusive)GetProcAddress(
+  acquire_srw_lock_exclusive = (PAcquireSRWLockExclusive)GetProcAddress(
       library, "AcquireSRWLockExclusive");
-  release_srw_lock_exclusive = (ReleaseSRWLockExclusive)GetProcAddress(
+  release_srw_lock_exclusive = (PReleaseSRWLockExclusive)GetProcAddress(
       library, "ReleaseSRWLockExclusive");
   acquire_srw_lock_shared =
-      (AcquireSRWLockShared)GetProcAddress(library, "AcquireSRWLockShared");
+      (PAcquireSRWLockShared)GetProcAddress(library, "AcquireSRWLockShared");
   release_srw_lock_shared =
-      (ReleaseSRWLockShared)GetProcAddress(library, "ReleaseSRWLockShared");
+      (PReleaseSRWLockShared)GetProcAddress(library, "ReleaseSRWLockShared");
 
   if (initialize_srw_lock && acquire_srw_lock_exclusive &&
       release_srw_lock_exclusive && acquire_srw_lock_shared &&
@@ -89,6 +88,18 @@
     RTC_LOG(LS_VERBOSE) << "Loaded Native RW Lock";
     native_rw_locks_supported = true;
   }
+#else
+  // On WinUWP the symbols loaded from this library are directly present
+  // in the headers and thus loading the library is not required (and
+  // manually loading libraries is restricted due to WinUWP sandboxing).
+  initialize_srw_lock = InitializeSRWLock;
+  acquire_srw_lock_exclusive = AcquireSRWLockExclusive;
+  release_srw_lock_exclusive = ReleaseSRWLockExclusive;
+  acquire_srw_lock_shared = AcquireSRWLockShared;
+  release_srw_lock_shared = ReleaseSRWLockShared;
+
+  native_rw_locks_supported = true;
+#endif  // !defined(WINUWP)
   return native_rw_locks_supported;
 }
 
diff --git a/rtc_base/timeutils.cc b/rtc_base/timeutils.cc
index dc5b611..0f79a87 100644
--- a/rtc_base/timeutils.cc
+++ b/rtc_base/timeutils.cc
@@ -45,6 +45,104 @@
   return g_clock;
 }
 
+#if defined(WINUWP)
+
+namespace {
+
+class TimeHelper final {
+ public:
+  TimeHelper(const TimeHelper&) = delete;
+
+  // Resets the clock based upon an NTP server. This routine must be called
+  // prior to the main system start-up to ensure all clocks are based upon
+  // an NTP server time if NTP synchronization is required. No critical
+  // section is used thus this method must be called prior to any clock
+  // routines being used.
+  static void SyncWithNtp(int64_t ntp_server_time_ms) {
+    auto& singleton = Singleton();
+    TIME_ZONE_INFORMATION time_zone;
+    GetTimeZoneInformation(&time_zone);
+    int64_t time_zone_bias_ns =
+        rtc::dchecked_cast<int64_t>(time_zone.Bias) * 60 * 1000 * 1000 * 1000;
+    singleton.app_start_time_ns_ =
+        (ntp_server_time_ms - kNTPTimeToUnixTimeEpochOffset) * 1000000 -
+        time_zone_bias_ns;
+    singleton.UpdateReferenceTime();
+  }
+
+  // Returns the number of nanoseconds that have passed since unix epoch.
+  static int64_t TicksNs() {
+    auto& singleton = Singleton();
+    int64_t result = 0;
+    LARGE_INTEGER qpcnt;
+    QueryPerformanceCounter(&qpcnt);
+    result = rtc::dchecked_cast<int64_t>(
+        (rtc::dchecked_cast<uint64_t>(qpcnt.QuadPart) * 100000 /
+         rtc::dchecked_cast<uint64_t>(singleton.os_ticks_per_second_)) *
+        10000);
+    result = singleton.app_start_time_ns_ + result -
+             singleton.time_since_os_start_ns_;
+    return result;
+  }
+
+ private:
+  TimeHelper() {
+    TIME_ZONE_INFORMATION time_zone;
+    GetTimeZoneInformation(&time_zone);
+    int64_t time_zone_bias_ns =
+        rtc::dchecked_cast<int64_t>(time_zone.Bias) * 60 * 1000 * 1000 * 1000;
+    FILETIME ft;
+    // This will give us system file in UTC format.
+    GetSystemTimeAsFileTime(&ft);
+    LARGE_INTEGER li;
+    li.HighPart = ft.dwHighDateTime;
+    li.LowPart = ft.dwLowDateTime;
+
+    app_start_time_ns_ = (li.QuadPart - kFileTimeToUnixTimeEpochOffset) * 100 -
+                         time_zone_bias_ns;
+
+    UpdateReferenceTime();
+  }
+
+  static TimeHelper& Singleton() {
+    static TimeHelper singleton;
+    return singleton;
+  }
+
+  void UpdateReferenceTime() {
+    LARGE_INTEGER qpfreq;
+    QueryPerformanceFrequency(&qpfreq);
+    os_ticks_per_second_ = rtc::dchecked_cast<int64_t>(qpfreq.QuadPart);
+
+    LARGE_INTEGER qpcnt;
+    QueryPerformanceCounter(&qpcnt);
+    time_since_os_start_ns_ = rtc::dchecked_cast<int64_t>(
+        (rtc::dchecked_cast<uint64_t>(qpcnt.QuadPart) * 100000 /
+         rtc::dchecked_cast<uint64_t>(os_ticks_per_second_)) *
+        10000);
+  }
+
+ private:
+  static constexpr uint64_t kFileTimeToUnixTimeEpochOffset =
+      116444736000000000ULL;
+  static constexpr uint64_t kNTPTimeToUnixTimeEpochOffset = 2208988800000L;
+
+  // The number of nanoseconds since unix system epoch
+  int64_t app_start_time_ns_;
+  // The number of nanoseconds since the OS started
+  int64_t time_since_os_start_ns_;
+  // The OS calculated ticks per second
+  int64_t os_ticks_per_second_;
+};
+
+}  // namespace
+
+void SyncWithNtp(int64_t time_from_ntp_server_ms) {
+  TimeHelper::SyncWithNtp(time_from_ntp_server_ms);
+}
+
+#endif  // defined(WINUWP)
+
 int64_t SystemTimeNanos() {
   int64_t ticks;
 #if defined(WEBRTC_MAC)
@@ -71,6 +169,8 @@
   clock_gettime(CLOCK_MONOTONIC, &ts);
   ticks = kNumNanosecsPerSec * static_cast<int64_t>(ts.tv_sec) +
           static_cast<int64_t>(ts.tv_nsec);
+#elif defined(WINUWP)
+  ticks = TimeHelper::TicksNs();
 #elif defined(WEBRTC_WIN)
   static volatile LONG last_timegettime = 0;
   static volatile int64_t num_wrap_timegettime = 0;
diff --git a/rtc_base/timeutils.h b/rtc_base/timeutils.h
index 4e38a03..c6ddd73 100644
--- a/rtc_base/timeutils.h
+++ b/rtc_base/timeutils.h
@@ -58,6 +58,12 @@
 // Returns previously set clock, or nullptr if no custom clock is being used.
 ClockInterface* GetClockForTesting();
 
+#if defined(WINUWP)
+// Synchronizes the current clock based upon an NTP server's epoch in
+// milliseconds.
+void SyncWithNtp(int64_t time_from_ntp_server_ms);
+#endif  // defined(WINUWP)
+
 // Returns the actual system time, even if a clock is set for testing.
 // Useful for timeouts while using a test clock, or for logging.
 int64_t SystemTimeNanos();
diff --git a/rtc_base/win/windows_version.cc b/rtc_base/win/windows_version.cc
index f10e42c..65ef4fd 100644
--- a/rtc_base/win/windows_version.cc
+++ b/rtc_base/win/windows_version.cc
@@ -28,6 +28,8 @@
 #error Creators Update SDK (10.0.15063.468) required.
 #endif
 
+#if !defined(WINUWP)
+
 namespace {
 
 typedef BOOL(WINAPI* GetProductInfoPtr)(DWORD, DWORD, DWORD, DWORD, PDWORD);
@@ -171,6 +173,8 @@
 
 }  // namespace
 
+#endif  // !defined(WINUWP)
+
 namespace rtc {
 namespace rtc_win {
 namespace {
@@ -221,6 +225,10 @@
 // this undocumented value appears to be similar to a patch number.
 // Returns 0 if the value does not exist or it could not be read.
 int GetUBR() {
+#if defined(WINUWP)
+  // The registry is not accessible for WinUWP sandboxed store applications.
+  return 0;
+#else
   // The values under the CurrentVersion registry hive are mirrored under
   // the corresponding Wow6432 hive.
   static constexpr wchar_t kRegKeyWindowsNTCurrentVersion[] =
@@ -236,6 +244,7 @@
   key.ReadValueDW(L"UBR", &ubr);
 
   return static_cast<int>(ubr);
+#endif  // defined(WINUWP)
 }
 
 }  // namespace
@@ -294,6 +303,7 @@
   processors_ = system_info.dwNumberOfProcessors;
   allocation_granularity_ = system_info.dwAllocationGranularity;
 
+#if !defined(WINUWP)
   GetProductInfoPtr get_product_info;
   DWORD os_type;
 
@@ -366,11 +376,21 @@
     // Windows is pre XP so we don't care but pick a safe default.
     version_type_ = SUITE_HOME;
   }
+#else
+  // WinUWP sandboxed store apps do not have a mechanism to determine
+  // product suite thus the most restricted suite is chosen.
+  version_type_ = SUITE_HOME;
+#endif  // !defined(WINUWP)
 }
 
 OSInfo::~OSInfo() {}
 
 std::string OSInfo::processor_model_name() {
+#if defined(WINUWP)
+  // WinUWP sandboxed store apps do not have the ability to
+  // probe the name of the current processor.
+  return "Unknown Processor (UWP)";
+#else
   if (processor_model_name_.empty()) {
     const wchar_t kProcessorNameString[] =
         L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
@@ -380,18 +400,24 @@
     processor_model_name_ = rtc::ToUtf8(value);
   }
   return processor_model_name_;
+#endif  // defined(WINUWP)
 }
 
 // static
 OSInfo::WOW64Status OSInfo::GetWOW64StatusForProcess(HANDLE process_handle) {
+  BOOL is_wow64;
+#if defined(WINUWP)
+  if (!IsWow64Process(process_handle, &is_wow64))
+    return WOW64_UNKNOWN;
+#else
   typedef BOOL(WINAPI * IsWow64ProcessFunc)(HANDLE, PBOOL);
   IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
       GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
   if (!is_wow64_process)
     return WOW64_DISABLED;
-  BOOL is_wow64 = FALSE;
   if (!(*is_wow64_process)(process_handle, &is_wow64))
     return WOW64_UNKNOWN;
+#endif  // defined(WINUWP)
   return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
 }
 
diff --git a/rtc_base/win32.cc b/rtc_base/win32.cc
index e3482e3..480d97b 100644
--- a/rtc_base/win32.cc
+++ b/rtc_base/win32.cc
@@ -331,6 +331,11 @@
   }
   // Replace forward slashes with backslashes
   std::replace(wfilename, wfilename + wlen, L'/', L'\\');
+#if defined(WINUWP)
+  // WinUWP sandboxed store applications require the paths to remain as
+  // relative paths.
+  filename->assign(wfilename);
+#else
   // Convert to complete filename
   DWORD full_len = ::GetFullPathName(wfilename, 0, nullptr, nullptr);
   if (0 == full_len) {
@@ -360,9 +365,18 @@
     // Already in long-path form.
   }
   filename->assign(start);
+#endif  // defined(WINUWP)
+
   return true;
 }
 
+// Windows UWP applications cannot obtain versioning information from
+// the sandbox with intention (as behehaviour based on OS versioning rather
+// than feature discovery / compilation flags is discoraged and Windows
+// 10 is living continously updated version unlike previous versions
+// of Windows).
+#if !defined(WINUWP)
+
 bool GetOsVersion(int* major, int* minor, int* build) {
   OSVERSIONINFO info = {0};
   info.dwOSVersionInfoSize = sizeof(info);
@@ -399,4 +413,6 @@
   return ret;
 }
 
+#endif  // !defined(WINUWP)
+
 }  // namespace rtc
diff --git a/rtc_base/win32.h b/rtc_base/win32.h
index a5fd541..004c6b4 100644
--- a/rtc_base/win32.h
+++ b/rtc_base/win32.h
@@ -54,6 +54,8 @@
   kWindowsVista = 6,
   kWindows10 = 10,
 };
+
+#if !defined(WINUWP)
 bool GetOsVersion(int* major, int* minor, int* build);
 
 inline bool IsWindowsVistaOrLater() {
@@ -87,6 +89,34 @@
           level < SECURITY_MANDATORY_MEDIUM_RID);
 }
 
+#else
+
+// When targetting WinUWP the OS must be Windows 10 (or greater) as lesser
+// Windows OS targets are not supported.
+inline bool IsWindowsVistaOrLater() {
+  return true;
+}
+
+inline bool IsWindowsXpOrLater() {
+  return true;
+}
+
+inline bool IsWindows8OrLater() {
+  return true;
+}
+
+inline bool IsWindows10OrLater() {
+  return true;
+}
+
+inline bool IsCurrentProcessLowIntegrity() {
+  // For WinUWP sandboxed store assume this is NOT a low integrity level run
+  // as application privileges can be requested in manifest as appropriate.
+  return true;
+}
+
+#endif  // !defined(WINUWP)
+
 }  // namespace rtc
 
 #endif  // RTC_BASE_WIN32_H_
diff --git a/system_wrappers/source/clock.cc b/system_wrappers/source/clock.cc
index 4f5d9cf..32cf1de 100644
--- a/system_wrappers/source/clock.cc
+++ b/system_wrappers/source/clock.cc
@@ -80,7 +80,29 @@
   }
 };
 
-#if defined(WEBRTC_WIN)
+#if defined(WINUWP)
+class WinUwpRealTimeClock final : public RealTimeClock {
+ public:
+  WinUwpRealTimeClock() = default;
+  ~WinUwpRealTimeClock() override {}
+
+ protected:
+  timeval CurrentTimeVal() const override {
+    // The rtc::SystemTimeNanos() method is already time offset from a base
+    // epoch value and might as be synchronized against an NTP time server as
+    // an added bonus.
+    auto nanos = rtc::SystemTimeNanos();
+
+    struct timeval tv;
+
+    tv.tv_sec = rtc::dchecked_cast<long>(nanos / 1000000000);
+    tv.tv_usec = rtc::dchecked_cast<long>(nanos / 1000);
+
+    return tv;
+  }
+};
+
+#elif defined(WEBRTC_WIN)
 // TODO(pbos): Consider modifying the implementation to synchronize itself
 // against system time (update ref_point_, make it non-const) periodically to
 // prevent clock drift.
@@ -202,7 +224,9 @@
 #endif  // defined(WEBRTC_POSIX)
 
 Clock* Clock::GetRealTimeClock() {
-#if defined(WEBRTC_WIN)
+#if defined(WINUWP)
+  static Clock* const clock = new WinUwpRealTimeClock();
+#elif defined(WEBRTC_WIN)
   static Clock* const clock = new WindowsRealTimeClock();
 #elif defined(WEBRTC_POSIX)
   static Clock* const clock = new UnixRealTimeClock();
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 7cd7b3e..f2d7937 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -6,8 +6,8 @@
 # in the file PATENTS.  All contributing project authors may
 # be found in the AUTHORS file in the root of the source tree.
 
-import("../webrtc.gni")
 import("//build/config/ui.gni")
+import("../webrtc.gni")
 if (is_android) {
   import("//build/config/android/rules.gni")
 }
@@ -647,9 +647,15 @@
     "statistics.h",
     "video_decoder_proxy_factory.h",
     "video_encoder_proxy_factory.h",
-    "win/run_loop_win.cc",
   ]
-  if (!is_win) {
+  if (current_os != "winuwp") {
+    # The filtering of *_win.cc is not done for WinUWP (intentionally) as
+    # most _win.cc files are compatible with WinUWP. However, the
+    # peek/dispatch Win32 runloops are entirely WinUWP incompatible thus
+    # WinUWP uses the generic runloop as defined for non-Windows targets.
+    sources += [ "win/run_loop_win.cc" ]
+  }
+  if (!is_win || current_os == "winuwp") {
     sources += [
       "run_loop.cc",
       "run_loop.h",
diff --git a/webrtc.gni b/webrtc.gni
index 5c5214e..16f3b29 100644
--- a/webrtc.gni
+++ b/webrtc.gni
@@ -233,8 +233,8 @@
 rtc_opus_dir = "//third_party/opus"
 
 # Desktop capturer is supported only on Windows, OSX and Linux.
-rtc_desktop_capture_supported =
-    is_win || is_mac || (is_linux && (rtc_use_x11 || rtc_use_pipewire))
+rtc_desktop_capture_supported = (is_win && current_os != "winuwp") || is_mac ||
+                                (is_linux && (rtc_use_x11 || rtc_use_pipewire))
 
 ###############################################################################
 # Templates