Backed out changeset be8383028bc0 (bug 1508468) for windows build bustage
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Wed, 21 Nov 2018 01:30:52 +0200
changeset 503824 f5dfe72df46786a1683699c3d78208a28d739527
parent 503823 5d6aa2af32d34012e3e79d0e0b8153927f2303ea
child 503825 af4aa01c64c52f2aa5c9eecd48b4a7cfc2bd1abd
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1508468
milestone65.0a1
backs outbe8383028bc02b2ab24a8102d0b1276f15af4764
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset be8383028bc0 (bug 1508468) for windows build bustage
browser/app/winlauncher/DllBlocklistWin.cpp
browser/app/winlauncher/DllBlocklistWin.h
browser/app/winlauncher/ErrorHandler.cpp
browser/app/winlauncher/ErrorHandler.h
browser/app/winlauncher/LaunchUnelevated.cpp
browser/app/winlauncher/LaunchUnelevated.h
browser/app/winlauncher/LauncherProcessWin.cpp
browser/app/winlauncher/LauncherResult.h
browser/app/winlauncher/NativeNt.h
browser/app/winlauncher/ProcThreadAttributes.h
browser/app/winlauncher/moz.build
browser/app/winlauncher/test/moz.build
ipc/mscom/COMApartmentRegion.h
widget/windows/WinHeaderOnlyUtils.h
--- a/browser/app/winlauncher/DllBlocklistWin.cpp
+++ b/browser/app/winlauncher/DllBlocklistWin.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 #include "NativeNt.h"
 #include "nsWindowsDllInterceptor.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Types.h"
 #include "mozilla/WindowsDllBlocklist.h"
-#include "mozilla/WinHeaderOnlyUtils.h"
 
 #define MOZ_LITERAL_UNICODE_STRING(s) \
   { \
     /* Length of the string in bytes, less the null terminator */ \
     sizeof(s) - sizeof(wchar_t), \
     /* Length of the string in bytes, including the null terminator */ \
     sizeof(s), \
     /* Pointer to the buffer */ \
@@ -326,124 +325,111 @@ class MOZ_RAII AutoVirtualProtect final
 {
 public:
   AutoVirtualProtect(void* aAddress, size_t aLength, DWORD aProtFlags,
                      HANDLE aTargetProcess = nullptr)
     : mAddress(aAddress)
     , mLength(aLength)
     , mTargetProcess(aTargetProcess)
     , mPrevProt(0)
-    , mError(WindowsError::CreateSuccess())
   {
-    if (!::VirtualProtectEx(aTargetProcess, aAddress, aLength, aProtFlags,
-                            &mPrevProt)) {
-      mError = WindowsError::FromLastError();
-    }
+    ::VirtualProtectEx(aTargetProcess, aAddress, aLength, aProtFlags,
+                       &mPrevProt);
   }
 
   ~AutoVirtualProtect()
   {
-    if (!mError) {
+    if (!mPrevProt) {
       return;
     }
 
     ::VirtualProtectEx(mTargetProcess, mAddress, mLength, mPrevProt,
                        &mPrevProt);
   }
 
   explicit operator bool() const
   {
-    return !!mError;
-  }
-
-  WindowsError GetError() const
-  {
-    return mError;
+    return !!mPrevProt;
   }
 
   AutoVirtualProtect(const AutoVirtualProtect&) = delete;
   AutoVirtualProtect(AutoVirtualProtect&&) = delete;
   AutoVirtualProtect& operator=(const AutoVirtualProtect&) = delete;
   AutoVirtualProtect& operator=(AutoVirtualProtect&&) = delete;
 
 private:
-  void*         mAddress;
-  size_t        mLength;
-  HANDLE        mTargetProcess;
-  DWORD         mPrevProt;
-  WindowsError  mError;
+  void*   mAddress;
+  size_t  mLength;
+  HANDLE  mTargetProcess;
+  DWORD   mPrevProt;
 };
 
-LauncherVoidResult
+bool
 InitializeDllBlocklistOOP(HANDLE aChildProcess)
 {
   mozilla::CrossProcessDllInterceptor intcpt(aChildProcess);
   intcpt.Init(L"ntdll.dll");
   bool ok = stub_NtMapViewOfSection.SetDetour(aChildProcess, intcpt,
                                               "NtMapViewOfSection",
                                               &patched_NtMapViewOfSection);
   if (!ok) {
-    return LAUNCHER_ERROR_GENERIC();
+    return false;
   }
 
   // Because aChildProcess has just been created in a suspended state, its
   // dynamic linker has not yet been initialized, thus its executable has
   // not yet been linked with ntdll.dll. If the blocklist hook intercepts a
   // library load prior to the link, the hook will be unable to invoke any
   // ntdll.dll functions.
   //
   // We know that the executable for our *current* process's binary is already
   // linked into ntdll, so we obtain the IAT from our own executable and graft
   // it onto the child process's IAT, thus enabling the child process's hook to
   // safely make its ntdll calls.
   mozilla::nt::PEHeaders ourExeImage(::GetModuleHandleW(nullptr));
   if (!ourExeImage) {
-    return LAUNCHER_ERROR_FROM_WIN32(ERROR_BAD_EXE_FORMAT);
+    return false;
   }
 
   PIMAGE_IMPORT_DESCRIPTOR impDesc = ourExeImage.GetIATForModule("ntdll.dll");
   if (!impDesc) {
-    return LAUNCHER_ERROR_FROM_WIN32(ERROR_INVALID_DATA);
+    return false;
   }
 
   // This is the pointer we need to write
   auto firstIatThunk = ourExeImage.template
     RVAToPtr<PIMAGE_THUNK_DATA>(impDesc->FirstThunk);
   if (!firstIatThunk) {
-    return LAUNCHER_ERROR_FROM_WIN32(ERROR_INVALID_DATA);
+    return false;
   }
 
   // Find the length by iterating through the table until we find a null entry
   PIMAGE_THUNK_DATA curIatThunk = firstIatThunk;
   while (mozilla::nt::PEHeaders::IsValid(curIatThunk)) {
     ++curIatThunk;
   }
 
   ptrdiff_t iatLength = (curIatThunk - firstIatThunk) * sizeof(IMAGE_THUNK_DATA);
 
   SIZE_T bytesWritten;
 
   { // Scope for prot
     AutoVirtualProtect prot(firstIatThunk, iatLength, PAGE_READWRITE,
                             aChildProcess);
     if (!prot) {
-      return LAUNCHER_ERROR_FROM_MOZ_WINDOWS_ERROR(prot.GetError());
+      return false;
     }
 
     ok = !!::WriteProcessMemory(aChildProcess, firstIatThunk, firstIatThunk,
                                 iatLength, &bytesWritten);
     if (!ok) {
-      return LAUNCHER_ERROR_FROM_LAST();
+      return false;
     }
   }
 
   // Tell the mozglue blocklist that we have bootstrapped
   uint32_t newFlags = eDllBlocklistInitFlagWasBootstrapped;
   ok = !!::WriteProcessMemory(aChildProcess, &gBlocklistInitFlags, &newFlags,
                               sizeof(newFlags), &bytesWritten);
-  if (!ok) {
-    return LAUNCHER_ERROR_FROM_LAST();
-  }
-
-  return Ok();
+  return ok;
 }
 
 } // namespace mozilla
--- a/browser/app/winlauncher/DllBlocklistWin.h
+++ b/browser/app/winlauncher/DllBlocklistWin.h
@@ -4,17 +4,15 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_DllBlocklistWin_h
 #define mozilla_DllBlocklistWin_h
 
 #include <windows.h>
 
-#include "LauncherResult.h"
-
 namespace mozilla {
 
-LauncherVoidResult InitializeDllBlocklistOOP(HANDLE aChildProcess);
+bool InitializeDllBlocklistOOP(HANDLE aChildProcess);
 
 } // namespace mozilla
 
 #endif // mozilla_DllBlocklistWin_h
deleted file mode 100644
--- a/browser/app/winlauncher/ErrorHandler.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-
-#include "ErrorHandler.h"
-
-namespace mozilla {
-
-void
-HandleLauncherError(const LauncherError& aError)
-{
-  // This is a placeholder error handler. We'll add telemetry and a fallback
-  // error log in future revisions.
-  WindowsError::UniqueString msg = aError.mError.AsString();
-  if (!msg) {
-    return;
-  }
-
-  ::MessageBoxW(nullptr, msg.get(), L"Firefox", MB_OK | MB_ICONERROR);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/browser/app/winlauncher/ErrorHandler.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_ErrorHandler_h
-#define mozilla_ErrorHandler_h
-
-#include "mozilla/Assertions.h"
-
-#include "LauncherResult.h"
-
-namespace mozilla {
-
-/**
- * All launcher process error handling should live in the implementation of
- * this function.
- */
-void HandleLauncherError(const LauncherError& aError);
-
-// This function is simply a convenience overload that automatically unwraps
-// the LauncherError from the provided LauncherResult and then forwards it to
-// the main implementation.
-template <typename T>
-inline void
-HandleLauncherError(const LauncherResult<T>& aResult)
-{
-  MOZ_ASSERT(aResult.isErr());
-  if (aResult.isOk()) {
-    return;
-  }
-
-  HandleLauncherError(aResult.unwrapErr());
-}
-
-// This function is simply a convenience overload that unwraps the provided
-// GenericErrorResult<LauncherError> and forwards it to the main implementation.
-inline void
-HandleLauncherError(const GenericErrorResult<LauncherError>& aResult)
-{
-  LauncherVoidResult r(aResult);
-  HandleLauncherError(r);
-}
-
-} // namespace mozilla
-
-#endif //  mozilla_ErrorHandler_h
--- a/browser/app/winlauncher/LaunchUnelevated.cpp
+++ b/browser/app/winlauncher/LaunchUnelevated.cpp
@@ -7,273 +7,254 @@
 #include "LaunchUnelevated.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/CmdLineAndEnvUtils.h"
 #include "mozilla/mscom/COMApartmentRegion.h"
 #include "mozilla/RefPtr.h"
 #include "nsWindowsHelpers.h"
 
-#include "LauncherResult.h"
-
 // For _bstr_t and _variant_t
 #include <comdef.h>
 #include <comutil.h>
 
 #include <windows.h>
 #include <exdisp.h>
 #include <objbase.h>
 #include <servprov.h>
 #include <shlobj.h>
 #include <shobjidl.h>
 
-static mozilla::LauncherResult<TOKEN_ELEVATION_TYPE>
+static mozilla::Maybe<TOKEN_ELEVATION_TYPE>
 GetElevationType(const nsAutoHandle& aToken)
 {
   DWORD retLen;
   TOKEN_ELEVATION_TYPE elevationType;
   if (!::GetTokenInformation(aToken.get(), TokenElevationType, &elevationType,
                              sizeof(elevationType), &retLen)) {
-    return LAUNCHER_ERROR_FROM_LAST();
+    return mozilla::Nothing();
   }
 
-  return elevationType;
+  return mozilla::Some(elevationType);
 }
 
-static mozilla::LauncherResult<bool>
+static mozilla::Maybe<bool>
 IsHighIntegrity(const nsAutoHandle& aToken)
 {
   DWORD reqdLen;
   if (!::GetTokenInformation(aToken.get(), TokenIntegrityLevel, nullptr, 0,
-                             &reqdLen)) {
-    DWORD err = ::GetLastError();
-    if (err != ERROR_INSUFFICIENT_BUFFER) {
-      return LAUNCHER_ERROR_FROM_WIN32(err);
-    }
+                             &reqdLen) &&
+      ::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+    return mozilla::Nothing();
   }
 
   auto buf = mozilla::MakeUnique<char[]>(reqdLen);
 
   if (!::GetTokenInformation(aToken.get(), TokenIntegrityLevel, buf.get(),
                              reqdLen, &reqdLen)) {
-    return LAUNCHER_ERROR_FROM_LAST();
+    return mozilla::Nothing();
   }
 
   auto tokenLabel = reinterpret_cast<PTOKEN_MANDATORY_LABEL>(buf.get());
 
   DWORD subAuthCount = *::GetSidSubAuthorityCount(tokenLabel->Label.Sid);
   DWORD integrityLevel = *::GetSidSubAuthority(tokenLabel->Label.Sid,
                                                subAuthCount - 1);
-  return integrityLevel > SECURITY_MANDATORY_MEDIUM_RID;
+  return mozilla::Some(integrityLevel > SECURITY_MANDATORY_MEDIUM_RID);
 }
 
-static mozilla::LauncherResult<HANDLE>
+static nsReturnRef<HANDLE>
 GetMediumIntegrityToken(const nsAutoHandle& aProcessToken)
 {
+  nsAutoHandle empty;
+
   HANDLE rawResult;
   if (!::DuplicateTokenEx(aProcessToken.get(), 0, nullptr,
                           SecurityImpersonation, TokenPrimary, &rawResult)) {
-
-    return LAUNCHER_ERROR_FROM_LAST();
+    return empty.out();
   }
 
   nsAutoHandle result(rawResult);
 
   BYTE mediumIlSid[SECURITY_MAX_SID_SIZE];
   DWORD mediumIlSidSize = sizeof(mediumIlSid);
   if (!::CreateWellKnownSid(WinMediumLabelSid, nullptr, mediumIlSid,
                             &mediumIlSidSize)) {
-    return LAUNCHER_ERROR_FROM_LAST();
+    return empty.out();
   }
 
   TOKEN_MANDATORY_LABEL integrityLevel = {};
   integrityLevel.Label.Attributes = SE_GROUP_INTEGRITY;
   integrityLevel.Label.Sid = reinterpret_cast<PSID>(mediumIlSid);
 
   if (!::SetTokenInformation(rawResult, TokenIntegrityLevel, &integrityLevel,
                              sizeof(integrityLevel))) {
-    return LAUNCHER_ERROR_FROM_LAST();
+    return empty.out();
   }
 
-  return result.disown();
+  return result.out();
 }
 
 namespace mozilla {
 
 // If we're running at an elevated integrity level, re-run ourselves at the
 // user's normal integrity level. We do this by locating the active explorer
 // shell, and then asking it to do a ShellExecute on our behalf. We do it this
 // way to ensure that the child process runs as the original user in the active
 // session; an elevated process could be running with different credentials than
 // those of the session.
 // See https://blogs.msdn.microsoft.com/oldnewthing/20131118-00/?p=2643
 
-LauncherVoidResult
+bool
 LaunchUnelevated(int aArgc, wchar_t* aArgv[])
 {
   // We require a single-threaded apartment to talk to Explorer.
   mscom::STARegion sta;
   if (!sta.IsValid()) {
-    return LAUNCHER_ERROR_FROM_HRESULT(sta.GetHResult());
+    return false;
   }
 
   // NB: Explorer is a local server, not an inproc server
   RefPtr<IShellWindows> shellWindows;
   HRESULT hr = ::CoCreateInstance(CLSID_ShellWindows, nullptr,
                                   CLSCTX_LOCAL_SERVER, IID_IShellWindows,
                                   getter_AddRefs(shellWindows));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   // 1. Find the shell view for the desktop.
   _variant_t loc(CSIDL_DESKTOP);
   _variant_t empty;
   long hwnd;
   RefPtr<IDispatch> dispDesktop;
   hr = shellWindows->FindWindowSW(&loc, &empty, SWC_DESKTOP, &hwnd,
                                   SWFO_NEEDDISPATCH, getter_AddRefs(dispDesktop));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   RefPtr<IServiceProvider> servProv;
   hr = dispDesktop->QueryInterface(IID_IServiceProvider, getter_AddRefs(servProv));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   RefPtr<IShellBrowser> browser;
   hr = servProv->QueryService(SID_STopLevelBrowser, IID_IShellBrowser,
                               getter_AddRefs(browser));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   RefPtr<IShellView> activeShellView;
   hr = browser->QueryActiveShellView(getter_AddRefs(activeShellView));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   // 2. Get the automation object for the desktop.
   RefPtr<IDispatch> dispView;
   hr = activeShellView->GetItemObject(SVGIO_BACKGROUND, IID_IDispatch,
                                       getter_AddRefs(dispView));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   RefPtr<IShellFolderViewDual> folderView;
   hr = dispView->QueryInterface(IID_IShellFolderViewDual,
                                 getter_AddRefs(folderView));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   // 3. Get the interface to IShellDispatch2
   RefPtr<IDispatch> dispShell;
   hr = folderView->get_Application(getter_AddRefs(dispShell));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   RefPtr<IShellDispatch2> shellDisp;
   hr = dispShell->QueryInterface(IID_IShellDispatch2, getter_AddRefs(shellDisp));
   if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
+    return false;
   }
 
   // 4. Now call IShellDispatch2::ShellExecute to ask Explorer to re-launch us.
 
   // Omit argv[0] because ShellExecute doesn't need it in params
   UniquePtr<wchar_t[]> cmdLine(MakeCommandLine(aArgc - 1, aArgv + 1));
   if (!cmdLine) {
-    return LAUNCHER_ERROR_GENERIC();
+    return false;
   }
 
   _bstr_t exe(aArgv[0]);
   _variant_t args(cmdLine.get());
   _variant_t operation(L"open");
   _variant_t directory;
   _variant_t showCmd(SW_SHOWNORMAL);
   hr = shellDisp->ShellExecute(exe, args, operation, directory, showCmd);
-  if (FAILED(hr)) {
-    return LAUNCHER_ERROR_FROM_HRESULT(hr);
-  }
-
-  return Ok();
+  return SUCCEEDED(hr);
 }
 
-LauncherResult<ElevationState>
+Maybe<ElevationState>
 GetElevationState(mozilla::LauncherFlags aFlags, nsAutoHandle& aOutMediumIlToken)
 {
   aOutMediumIlToken.reset();
 
   const DWORD tokenFlags = TOKEN_QUERY | TOKEN_DUPLICATE |
                            TOKEN_ADJUST_DEFAULT | TOKEN_ASSIGN_PRIMARY;
   HANDLE rawToken;
   if (!::OpenProcessToken(::GetCurrentProcess(), tokenFlags, &rawToken)) {
-    return LAUNCHER_ERROR_FROM_LAST();
+    return Nothing();
   }
 
   nsAutoHandle token(rawToken);
 
-  LauncherResult<TOKEN_ELEVATION_TYPE> elevationType = GetElevationType(token);
-  if (elevationType.isErr()) {
-    return LAUNCHER_ERROR_FROM_RESULT(elevationType);
+  Maybe<TOKEN_ELEVATION_TYPE> elevationType = GetElevationType(token);
+  if (!elevationType) {
+    return Nothing();
   }
 
-  switch (elevationType.unwrap()) {
+  switch (elevationType.value()) {
     case TokenElevationTypeLimited:
-      return ElevationState::eNormalUser;
+      return Some(ElevationState::eNormalUser);
     case TokenElevationTypeFull:
       // If we want to start a non-elevated browser process and wait on it,
       // we're going to need a medium IL token.
       if ((aFlags & (mozilla::LauncherFlags::eWaitForBrowser |
                      mozilla::LauncherFlags::eNoDeelevate)) ==
           mozilla::LauncherFlags::eWaitForBrowser) {
-        LauncherResult<HANDLE> tokenResult =
-          GetMediumIntegrityToken(token);
-        if (tokenResult.isOk()) {
-          aOutMediumIlToken.own(tokenResult.unwrap());
-        } else {
-          return LAUNCHER_ERROR_FROM_RESULT(tokenResult);
-        }
+        aOutMediumIlToken = GetMediumIntegrityToken(token);
       }
 
-      return ElevationState::eElevated;
+      return Some(ElevationState::eElevated);
     case TokenElevationTypeDefault:
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Was a new value added to the enumeration?");
-      return LAUNCHER_ERROR_GENERIC();
+      return Nothing();
   }
 
   // In this case, UAC is disabled. We do not yet know whether or not we are
   // running at high integrity. If we are at high integrity, we can't relaunch
   // ourselves in a non-elevated state via Explorer, as we would just end up in
   // an infinite loop of launcher processes re-launching themselves.
 
-  LauncherResult<bool> isHighIntegrity = IsHighIntegrity(token);
-  if (isHighIntegrity.isErr()) {
-    return LAUNCHER_ERROR_FROM_RESULT(isHighIntegrity);
+  Maybe<bool> isHighIntegrity = IsHighIntegrity(token);
+  if (!isHighIntegrity) {
+    return Nothing();
   }
 
-  if (!isHighIntegrity.unwrap()) {
-    return ElevationState::eNormalUser;
+  if (!isHighIntegrity.value()) {
+    return Some(ElevationState::eNormalUser);
   }
 
   if (!(aFlags & mozilla::LauncherFlags::eNoDeelevate)) {
-    LauncherResult<HANDLE> tokenResult =
-      GetMediumIntegrityToken(token);
-    if (tokenResult.isOk()) {
-      aOutMediumIlToken.own(tokenResult.unwrap());
-    } else {
-      return LAUNCHER_ERROR_FROM_RESULT(tokenResult);
-    }
+    aOutMediumIlToken = GetMediumIntegrityToken(token);
   }
 
-  return ElevationState::eHighIntegrityNoUAC;
+  return Some(ElevationState::eHighIntegrityNoUAC);
 }
 
 } // namespace mozilla
 
--- a/browser/app/winlauncher/LaunchUnelevated.h
+++ b/browser/app/winlauncher/LaunchUnelevated.h
@@ -3,30 +3,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_LaunchUnelevated_h
 #define mozilla_LaunchUnelevated_h
 
 #include "LauncherProcessWin.h"
-#include "LauncherResult.h"
 #include "mozilla/Maybe.h"
 #include "nsWindowsHelpers.h"
 
 namespace mozilla {
 
 enum class ElevationState
 {
   eNormalUser = 0,
   eElevated = (1 << 0),
   eHighIntegrityNoUAC = (1 << 1),
 };
 
-LauncherResult<ElevationState>
+mozilla::Maybe<ElevationState>
 GetElevationState(LauncherFlags aFlags, nsAutoHandle& aOutMediumIlToken);
 
-LauncherVoidResult LaunchUnelevated(int aArgc, wchar_t* aArgv[]);
+bool LaunchUnelevated(int aArgc, wchar_t* aArgv[]);
 
 } // namespace mozilla
 
 #endif // mozilla_LaunchUnelevated_h
 
--- a/browser/app/winlauncher/LauncherProcessWin.cpp
+++ b/browser/app/winlauncher/LauncherProcessWin.cpp
@@ -20,36 +20,34 @@
 #include "mozilla/WindowsVersion.h"
 #include "mozilla/WinHeaderOnlyUtils.h"
 #include "nsWindowsHelpers.h"
 
 #include <windows.h>
 #include <processthreadsapi.h>
 
 #include "DllBlocklistWin.h"
-#include "ErrorHandler.h"
-#include "LauncherResult.h"
 #include "LaunchUnelevated.h"
 #include "ProcThreadAttributes.h"
 
 /**
  * At this point the child process has been created in a suspended state. Any
  * additional startup work (eg, blocklist setup) should go here.
  *
  * @return true if browser startup should proceed, otherwise false.
  */
-static mozilla::LauncherVoidResult
+static bool
 PostCreationSetup(HANDLE aChildProcess, HANDLE aChildMainThread,
                   const bool aIsSafeMode)
 {
   // The launcher process's DLL blocking code is incompatible with ASAN because
   // it is able to execute before ASAN itself has even initialized.
   // Also, the AArch64 build doesn't yet have a working interceptor.
 #if defined(MOZ_ASAN) || defined(_M_ARM64)
-  return Ok();
+  return true;
 #else
   return mozilla::InitializeDllBlocklistOOP(aChildProcess);
 #endif // defined(MOZ_ASAN) || defined(_M_ARM64)
 }
 
 #if !defined(PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_ON)
 # define PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_ON (0x00000001ULL << 60)
 #endif // !defined(PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_ON)
@@ -67,16 +65,37 @@ SetProcessMitigationPolicy(PROCESS_MITIG
 static void
 SetMitigationPolicies(mozilla::ProcThreadAttributes& aAttrs, const bool aIsSafeMode)
 {
   if (mozilla::IsWin10AnniversaryUpdateOrLater()) {
     aAttrs.AddMitigationPolicy(PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_ON);
   }
 }
 
+static void
+ShowError(DWORD aError = ::GetLastError())
+{
+  if (aError == ERROR_SUCCESS) {
+    return;
+  }
+
+  LPWSTR rawMsgBuf = nullptr;
+  DWORD result = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                                  FORMAT_MESSAGE_FROM_SYSTEM |
+                                  FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
+                                  aError, 0, reinterpret_cast<LPWSTR>(&rawMsgBuf),
+                                  0, nullptr);
+  if (!result) {
+    return;
+  }
+
+  ::MessageBoxW(nullptr, rawMsgBuf, L"Firefox", MB_OK | MB_ICONERROR);
+  ::LocalFree(rawMsgBuf);
+}
+
 static mozilla::LauncherFlags
 ProcessCmdLine(int& aArgc, wchar_t* aArgv[])
 {
   mozilla::LauncherFlags result = mozilla::LauncherFlags::eNone;
 
   if (mozilla::CheckArg(aArgc, aArgv, L"wait-for-browser",
                         static_cast<const wchar_t**>(nullptr),
                         mozilla::CheckArgFlag::RemoveArg) == mozilla::ARG_FOUND ||
@@ -142,73 +161,79 @@ MaybeBreakForBrowserDebugging()
   DWORD pauseLenMs = wcstoul(pauseLenS, nullptr, 10) * 1000;
   printf_stderr("\n\nBROWSERBROWSERBROWSERBROWSER\n  debug me @ %lu\n\n",
                 ::GetCurrentProcessId());
   ::Sleep(pauseLenMs);
 }
 
 #if defined(MOZ_LAUNCHER_PROCESS)
 
-static mozilla::LauncherResult<bool>
+static bool
 IsSameBinaryAsParentProcess()
 {
-  mozilla::LauncherResult<DWORD> parentPid = mozilla::nt::GetParentProcessId();
-  if (parentPid.isErr()) {
-    return LAUNCHER_ERROR_FROM_RESULT(parentPid);
+  mozilla::Maybe<DWORD> parentPid = mozilla::nt::GetParentProcessId();
+  if (!parentPid) {
+    // If NtQueryInformationProcess failed (in GetParentProcessId()),
+    // we should not behave as the launcher process because it will also
+    // likely to fail in child processes.
+    MOZ_CRASH("NtQueryInformationProcess failed");
   }
 
   nsAutoHandle parentProcess(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
-                                           FALSE, parentPid.unwrap()));
+                                           FALSE, parentPid.value()));
   if (!parentProcess.get()) {
-    return LAUNCHER_ERROR_FROM_LAST();
+    // If OpenProcess failed, the parent process may not be present,
+    // may be already terminated, etc. So we will have to behave as the
+    // launcher proces in this case.
+    return false;
   }
 
   WCHAR parentExe[MAX_PATH + 1] = {};
   DWORD parentExeLen = mozilla::ArrayLength(parentExe);
   if (!::QueryFullProcessImageNameW(parentProcess.get(), PROCESS_NAME_NATIVE,
                                     parentExe, &parentExeLen)) {
-    return LAUNCHER_ERROR_FROM_LAST();
+    // If QueryFullProcessImageNameW failed, we should not behave as the
+    // launcher process for the same reason as NtQueryInformationProcess.
+    MOZ_CRASH("QueryFullProcessImageNameW failed");
   }
 
   WCHAR ourExe[MAX_PATH + 1] = {};
   DWORD ourExeOk = ::GetModuleFileNameW(nullptr, ourExe,
                                         mozilla::ArrayLength(ourExe));
   if (!ourExeOk || ourExeOk == mozilla::ArrayLength(ourExe)) {
-    return LAUNCHER_ERROR_FROM_LAST();
+    // If GetModuleFileNameW failed, we should not behave as the launcher
+    // process for the same reason as NtQueryInformationProcess.
+    MOZ_CRASH("GetModuleFileNameW failed");
   }
 
-  mozilla::WindowsErrorResult<bool> isSame =
+  mozilla::Maybe<bool> isSame =
     mozilla::DoPathsPointToIdenticalFile(parentExe, ourExe,
-                                         mozilla::PathType::eNtPath);
-  if (isSame.isErr()) {
-    return LAUNCHER_ERROR_FROM_MOZ_WINDOWS_ERROR(isSame.unwrapErr());
+                                         mozilla::eNtPath);
+  if (!isSame) {
+    // If DoPathsPointToIdenticalFile failed, we should not behave as the
+    // launcher process for the same reason as NtQueryInformationProcess.
+    MOZ_CRASH("DoPathsPointToIdenticalFile failed");
   }
-
-  return isSame.unwrap();
+  return isSame.value();
 }
 
 #endif // defined(MOZ_LAUNCHER_PROCESS)
 
 namespace mozilla {
 
 bool
 RunAsLauncherProcess(int& argc, wchar_t** argv)
 {
   // NB: We run all tests in this function instead of returning early in order
   // to ensure that all side effects take place, such as clearing environment
   // variables.
   bool result = false;
 
 #if defined(MOZ_LAUNCHER_PROCESS)
-  LauncherResult<bool> isSame = IsSameBinaryAsParentProcess();
-  if (isSame.isOk()) {
-    result = !isSame.unwrap();
-  } else {
-    HandleLauncherError(isSame.unwrapErr());
-  }
+  result = !IsSameBinaryAsParentProcess();
 #endif // defined(MOZ_LAUNCHER_PROCESS)
 
   if (mozilla::EnvHasValue("MOZ_LAUNCHER_PROCESS")) {
     mozilla::SaveToEnv("MOZ_LAUNCHER_PROCESS=");
     result = true;
   }
 
   result |= CheckArg(argc, argv, L"launcher",
@@ -238,55 +263,47 @@ LauncherMain(int argc, wchar_t* argv[])
       DebugOnly<BOOL> setOk = pSetProcessMitigationPolicy(ProcessImageLoadPolicy,
                                                           &imgLoadPol,
                                                           sizeof(imgLoadPol));
       MOZ_ASSERT(setOk);
     }
   }
 
   if (!SetArgv0ToFullBinaryPath(argv)) {
-    HandleLauncherError(LAUNCHER_ERROR_GENERIC());
+    ShowError();
     return 1;
   }
 
   LauncherFlags flags = ProcessCmdLine(argc, argv);
 
   nsAutoHandle mediumIlToken;
-  LauncherResult<ElevationState> elevationState = GetElevationState(flags, mediumIlToken);
-  if (elevationState.isErr()) {
-    HandleLauncherError(elevationState);
+  Maybe<ElevationState> elevationState = GetElevationState(flags, mediumIlToken);
+  if (!elevationState) {
     return 1;
   }
 
   // If we're elevated, we should relaunch ourselves as a normal user.
   // Note that we only call LaunchUnelevated when we don't need to wait for the
   // browser process.
-  if (elevationState.unwrap() == ElevationState::eElevated &&
+  if (elevationState.value() == ElevationState::eElevated &&
       !(flags & (LauncherFlags::eWaitForBrowser | LauncherFlags::eNoDeelevate)) &&
       !mediumIlToken.get()) {
-    LauncherVoidResult launchedUnelevated = LaunchUnelevated(argc, argv);
-    bool failed = launchedUnelevated.isErr();
-    if (failed) {
-      HandleLauncherError(launchedUnelevated);
-    }
-
-    return failed;
+    return !LaunchUnelevated(argc, argv);
   }
 
   // Now proceed with setting up the parameters for process creation
   UniquePtr<wchar_t[]> cmdLine(MakeCommandLine(argc, argv));
   if (!cmdLine) {
-    HandleLauncherError(LAUNCHER_ERROR_GENERIC());
     return 1;
   }
 
   const Maybe<bool> isSafeMode = IsSafeModeRequested(argc, argv,
                                                      SafeModeFlag::NoKeyPressCheck);
   if (!isSafeMode) {
-    HandleLauncherError(LAUNCHER_ERROR_FROM_WIN32(ERROR_INVALID_PARAMETER));
+    ShowError(ERROR_INVALID_PARAMETER);
     return 1;
   }
 
   ProcThreadAttributes attrs;
   SetMitigationPolicies(attrs, isSafeMode.value());
 
   HANDLE stdHandles[] = {
     ::GetStdHandle(STD_INPUT_HANDLE),
@@ -294,25 +311,25 @@ LauncherMain(int argc, wchar_t* argv[])
     ::GetStdHandle(STD_ERROR_HANDLE)
   };
 
   attrs.AddInheritableHandles(stdHandles);
 
   DWORD creationFlags = CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT;
 
   STARTUPINFOEXW siex;
-  LauncherResult<bool> attrsOk = attrs.AssignTo(siex);
-  if (attrsOk.isErr()) {
-    HandleLauncherError(attrsOk);
+  Maybe<bool> attrsOk = attrs.AssignTo(siex);
+  if (!attrsOk) {
+    ShowError();
     return 1;
   }
 
   BOOL inheritHandles = FALSE;
 
-  if (attrsOk.unwrap()) {
+  if (attrsOk.value()) {
     creationFlags |= EXTENDED_STARTUPINFO_PRESENT;
 
     if (attrs.HasInheritableHandles()) {
       siex.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
       siex.StartupInfo.hStdInput = stdHandles[0];
       siex.StartupInfo.hStdOutput = stdHandles[1];
       siex.StartupInfo.hStdError = stdHandles[2];
 
@@ -332,33 +349,26 @@ LauncherMain(int argc, wchar_t* argv[])
                                       &siex.StartupInfo, &pi);
   } else {
     createOk = ::CreateProcessW(argv[0], cmdLine.get(), nullptr, nullptr,
                                 inheritHandles, creationFlags, nullptr, nullptr,
                                 &siex.StartupInfo, &pi);
   }
 
   if (!createOk) {
-    HandleLauncherError(LAUNCHER_ERROR_FROM_LAST());
+    ShowError();
     return 1;
   }
 
   nsAutoHandle process(pi.hProcess);
   nsAutoHandle mainThread(pi.hThread);
 
-  LauncherVoidResult setupResult =
-    PostCreationSetup(process.get(), mainThread.get(), isSafeMode.value());
-  if (setupResult.isErr()) {
-    HandleLauncherError(setupResult);
-    ::TerminateProcess(process.get(), 1);
-    return 1;
-  }
-
-  if (::ResumeThread(mainThread.get()) == static_cast<DWORD>(-1)) {
-    HandleLauncherError(LAUNCHER_ERROR_FROM_LAST());
+  if (!PostCreationSetup(process.get(), mainThread.get(), isSafeMode.value()) ||
+      ::ResumeThread(mainThread.get()) == static_cast<DWORD>(-1)) {
+    ShowError();
     ::TerminateProcess(process.get(), 1);
     return 1;
   }
 
   if (flags & LauncherFlags::eWaitForBrowser) {
     DWORD exitCode;
     if (::WaitForSingleObject(process.get(), INFINITE) == WAIT_OBJECT_0 &&
         ::GetExitCodeProcess(process.get(), &exitCode)) {
deleted file mode 100644
--- a/browser/app/winlauncher/LauncherResult.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_LauncherResult_h
-#define mozilla_LauncherResult_h
-
-#include "mozilla/Result.h"
-#include "mozilla/WinHeaderOnlyUtils.h"
-
-namespace mozilla {
-
-struct LauncherError
-{
-  LauncherError(const char* aFile, int aLine, WindowsError aWin32Error)
-    : mFile(aFile)
-    , mLine(aLine)
-    , mError(aWin32Error)
-  {}
-
-  const char* mFile;
-  int mLine;
-  WindowsError mError;
-};
-
-template <typename T>
-using LauncherResult = Result<T, LauncherError>;
-
-using LauncherVoidResult = Result<Ok, LauncherError>;
-
-} // namespace mozilla
-
-#define LAUNCHER_ERROR_GENERIC() \
-  ::mozilla::Err(::mozilla::LauncherError(__FILE__, __LINE__, \
-                 ::mozilla::WindowsError::CreateGeneric()))
-
-#define LAUNCHER_ERROR_FROM_WIN32(err) \
-  ::mozilla::Err(::mozilla::LauncherError(__FILE__, __LINE__, \
-                 ::mozilla::WindowsError::FromWin32Error(err)))
-
-#define LAUNCHER_ERROR_FROM_LAST() \
-  ::mozilla::Err(::mozilla::LauncherError(__FILE__, __LINE__, \
-                 ::mozilla::WindowsError::FromWin32Error(::GetLastError())))
-
-#define LAUNCHER_ERROR_FROM_NTSTATUS(ntstatus) \
-  ::mozilla::Err(::mozilla::LauncherError(__FILE__, __LINE__, \
-                 ::mozilla::WindowsError::FromNtStatus(ntstatus)))
-
-#define LAUNCHER_ERROR_FROM_HRESULT(hresult) \
-  ::mozilla::Err(::mozilla::LauncherError(__FILE__, __LINE__, \
-                 ::mozilla::WindowsError::FromHResult(hresult)))
-
-// This macro enables moving of a mozilla::LauncherError from a
-// mozilla::LauncherResult<Foo> into a mozilla::LauncherResult<Bar>
-#define LAUNCHER_ERROR_FROM_RESULT(result) \
-  ::mozilla::Err(result.unwrapErr())
-
-// This macro wraps the supplied WindowsError with a LauncherError
-#define LAUNCHER_ERROR_FROM_MOZ_WINDOWS_ERROR(err) \
-  ::mozilla::Err(::mozilla::LauncherError(__FILE__, __LINE__, err))
-
-#endif // mozilla_LauncherResult_h
--- a/browser/app/winlauncher/NativeNt.h
+++ b/browser/app/winlauncher/NativeNt.h
@@ -13,18 +13,17 @@
 
 #include <stdint.h>
 #include <windows.h>
 #include <winnt.h>
 #include <winternl.h>
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
-
-#include "LauncherResult.h"
+#include "mozilla/Maybe.h"
 
 extern "C" {
 
 #if !defined(STATUS_ACCESS_DENIED)
 #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
 #endif // !defined(STATUS_ACCESS_DENIED)
 
 #if !defined(STATUS_DLL_NOT_FOUND)
@@ -564,39 +563,38 @@ private:
 inline HANDLE
 RtlGetProcessHeap()
 {
   PTEB teb = ::NtCurrentTeb();
   PPEB peb = teb->ProcessEnvironmentBlock;
   return peb->Reserved4[1];
 }
 
-inline LauncherResult<DWORD>
+inline Maybe<DWORD>
 GetParentProcessId()
 {
   struct PROCESS_BASIC_INFORMATION
   {
     NTSTATUS ExitStatus;
     PPEB PebBaseAddress;
     ULONG_PTR AffinityMask;
     LONG BasePriority;
     ULONG_PTR UniqueProcessId;
     ULONG_PTR InheritedFromUniqueProcessId;
   };
 
-  const HANDLE kCurrentProcess = reinterpret_cast<HANDLE>(-1);
   ULONG returnLength;
   PROCESS_BASIC_INFORMATION pbi = {};
-  NTSTATUS status = ::NtQueryInformationProcess(kCurrentProcess,
+  NTSTATUS status = ::NtQueryInformationProcess(::GetCurrentProcess(),
                                                 ProcessBasicInformation,
                                                 &pbi, sizeof(pbi),
                                                 &returnLength);
   if (!NT_SUCCESS(status)) {
-    return LAUNCHER_ERROR_FROM_NTSTATUS(status);
+    return Nothing();
   }
 
-  return static_cast<DWORD>(pbi.InheritedFromUniqueProcessId & 0xFFFFFFFF);
+  return Some(static_cast<DWORD>(pbi.InheritedFromUniqueProcessId & 0xFFFFFFFF));
 }
 
 } // namespace nt
 } // namespace mozilla
 
 #endif // mozilla_NativeNt_h
--- a/browser/app/winlauncher/ProcThreadAttributes.h
+++ b/browser/app/winlauncher/ProcThreadAttributes.h
@@ -81,22 +81,24 @@ public:
   }
 
   bool HasInheritableHandles() const
   {
     return !mInheritableHandles.empty();
   }
 
   /**
-   * @return false if the STARTUPINFOEXW::lpAttributeList was set to null
-   *               as expected based on the state of |this|;
-   *         true  if the STARTUPINFOEXW::lpAttributeList was set to
-   *               non-null;
+   * @return Some(false) if the STARTUPINFOEXW::lpAttributeList was set to null
+   *                     as expected based on the state of |this|;
+   *         Some(true)  if the STARTUPINFOEXW::lpAttributeList was set to
+   *                     non-null;
+   *         Nothing()   if something went wrong in the assignment and we should
+   *                     not proceed.
    */
-  LauncherResult<bool> AssignTo(STARTUPINFOEXW& aSiex)
+  Maybe<bool> AssignTo(STARTUPINFOEXW& aSiex)
   {
     ZeroMemory(&aSiex, sizeof(STARTUPINFOEXW));
 
     // We'll set the size to sizeof(STARTUPINFOW) until we determine whether the
     // extended fields will be used.
     aSiex.StartupInfo.cb = sizeof(STARTUPINFOW);
 
     DWORD numAttributes = 0;
@@ -104,69 +106,67 @@ public:
       ++numAttributes;
     }
 
     if (HasInheritableHandles()) {
       ++numAttributes;
     }
 
     if (!numAttributes) {
-      return false;
+      return Some(false);
     }
 
     SIZE_T listSize = 0;
     if (!::InitializeProcThreadAttributeList(nullptr, numAttributes, 0,
-                                             &listSize)) {
-      DWORD err = ::GetLastError();
-      if (err != ERROR_INSUFFICIENT_BUFFER) {
-        return LAUNCHER_ERROR_FROM_WIN32(err);
-      }
+                                             &listSize) &&
+        ::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+      return Nothing();
     }
 
     auto buf = MakeUnique<char[]>(listSize);
 
     LPPROC_THREAD_ATTRIBUTE_LIST tmpList =
       reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(buf.get());
 
     if (!::InitializeProcThreadAttributeList(tmpList, numAttributes, 0,
                                              &listSize)) {
-      return LAUNCHER_ERROR_FROM_LAST();
+      return Nothing();
     }
 
     // Transfer buf to a ProcThreadAttributeListPtr - now that the list is
     // initialized, we are no longer dealing with a plain old char array. We
     // must now deinitialize the attribute list before deallocating the
     // underlying buffer.
     ProcThreadAttributeListPtr
       attrList(reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(buf.release()));
 
     if (mMitigationPolicies) {
       if (!::UpdateProcThreadAttribute(attrList.get(), 0,
                                        PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY,
                                        &mMitigationPolicies,
                                        sizeof(mMitigationPolicies), nullptr,
                                        nullptr)) {
-        return LAUNCHER_ERROR_FROM_LAST();
+        return Nothing();
       }
     }
 
     if (!mInheritableHandles.empty()) {
       if (!::UpdateProcThreadAttribute(attrList.get(), 0,
                                        PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
                                        mInheritableHandles.begin(),
                                        mInheritableHandles.length() * sizeof(HANDLE),
                                        nullptr, nullptr)) {
-        return LAUNCHER_ERROR_FROM_LAST();
+        return Nothing();
       }
     }
 
     mAttrList = std::move(attrList);
     aSiex.lpAttributeList = mAttrList.get();
     aSiex.StartupInfo.cb = sizeof(STARTUPINFOEXW);
-    return true;
+    return Some(true);
   }
 
 private:
   static const uint32_t kNumInline = 3; // Inline storage for the std handles
 
   DWORD64                     mMitigationPolicies;
   Vector<HANDLE, kNumInline>  mInheritableHandles;
   ProcThreadAttributeListPtr  mAttrList;
--- a/browser/app/winlauncher/moz.build
+++ b/browser/app/winlauncher/moz.build
@@ -5,17 +5,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 Library('winlauncher')
 
 FORCE_STATIC_LIB = True
 
 UNIFIED_SOURCES += [
     'DllBlocklistWin.cpp',
-    'ErrorHandler.cpp',
     'LauncherProcessWin.cpp',
     'LaunchUnelevated.cpp',
 ]
 
 OS_LIBS += [
     'ntdll',
     'oleaut32',
     'ole32',
--- a/browser/app/winlauncher/test/moz.build
+++ b/browser/app/winlauncher/test/moz.build
@@ -1,17 +1,17 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DisableStlWrapping()
 
-GeckoCppUnitTests(['TestNativeNt'])
+CppUnitTests(['TestNativeNt'])
 
 LOCAL_INCLUDES += [
     '/browser/app/winlauncher',
 ]
 
 OS_LIBS += [
     'mincore',
     'ntdll',
--- a/ipc/mscom/COMApartmentRegion.h
+++ b/ipc/mscom/COMApartmentRegion.h
@@ -38,21 +38,16 @@ public:
     return mInitResult == S_OK;
   }
 
   bool IsValid() const
   {
     return SUCCEEDED(mInitResult);
   }
 
-  HRESULT GetHResult() const
-  {
-    return mInitResult;
-  }
-
 private:
   COMApartmentRegion(const COMApartmentRegion&) = delete;
   COMApartmentRegion& operator=(const COMApartmentRegion&) = delete;
   COMApartmentRegion(COMApartmentRegion&&) = delete;
   COMApartmentRegion& operator=(COMApartmentRegion&&) = delete;
 
   HRESULT mInitResult;
 };
--- a/widget/windows/WinHeaderOnlyUtils.h
+++ b/widget/windows/WinHeaderOnlyUtils.h
@@ -3,26 +3,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_WinHeaderOnlyUtils_h
 #define mozilla_WinHeaderOnlyUtils_h
 
 #include <windows.h>
-#include <winerror.h>
-#include <winnt.h>
 #include <winternl.h>
 
-#include "mozilla/Assertions.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/DynamicallyLinkedFunctionPtr.h"
 #include "mozilla/Maybe.h"
-#include "mozilla/Result.h"
-#include "mozilla/UniquePtr.h"
 #include "mozilla/WindowsVersion.h"
 #include "nsWindowsHelpers.h"
 
 /**
  * This header is intended for self-contained, header-only, utility code for
  * Win32. It may be used outside of xul.dll, in places such as firefox.exe or
  * mozglue.dll. If your code creates dependencies on Mozilla libraries, you
  * should put it elsewhere.
@@ -34,175 +27,18 @@ typedef struct _FILE_ID_INFO
   ULONGLONG   VolumeSerialNumber;
   FILE_ID_128 FileId;
 } FILE_ID_INFO;
 
 #define FileIdInfo ((FILE_INFO_BY_HANDLE_CLASS)18)
 
 #endif // _WIN32_WINNT < _WIN32_WINNT_WIN8
 
-#if !defined(STATUS_SUCCESS)
-#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
-#endif // !defined(STATUS_SUCCESS)
-
 namespace mozilla {
 
-class WindowsError final
-{
-private:
-  // HRESULT and NTSTATUS are both typedefs of LONG, so we cannot use
-  // overloading to properly differentiate between the two. Instead we'll use
-  // static functions to convert the various error types to HRESULTs before
-  // instantiating.
-  explicit WindowsError(HRESULT aHResult)
-    : mHResult(aHResult)
-  {
-  }
-
-public:
-  using UniqueString = UniquePtr<WCHAR[], LocalFreeDeleter>;
-
-  static WindowsError FromNtStatus(NTSTATUS aNtStatus)
-  {
-    if (aNtStatus == STATUS_SUCCESS) {
-      // Special case: we don't want to set FACILITY_NT_BIT
-      // (HRESULT_FROM_NT does not handle this case, unlike HRESULT_FROM_WIN32)
-      return WindowsError(S_OK);
-    }
-
-    return WindowsError(HRESULT_FROM_NT(aNtStatus));
-  }
-
-  static WindowsError FromHResult(HRESULT aHResult)
-  {
-    return WindowsError(aHResult);
-  }
-
-  static WindowsError FromWin32Error(DWORD aWin32Err)
-  {
-    return WindowsError(HRESULT_FROM_WIN32(aWin32Err));
-  }
-
-  static WindowsError FromLastError()
-  {
-    return FromWin32Error(::GetLastError());
-  }
-
-  static WindowsError CreateSuccess()
-  {
-    return WindowsError(S_OK);
-  }
-
-  static WindowsError CreateGeneric()
-  {
-    return FromWin32Error(ERROR_UNIDENTIFIED_ERROR);
-  }
-
-  explicit operator bool() const
-  {
-    return SUCCEEDED(mHResult);
-  }
-
-  bool IsAvailableAsWin32Error() const
-  {
-    return IsAvailableAsNtStatus() ||
-           HRESULT_FACILITY(mHResult) == FACILITY_WIN32;
-  }
-
-  bool IsAvailableAsNtStatus() const
-  {
-    return mHResult == S_OK || (mHResult & FACILITY_NT_BIT);
-  }
-
-  bool IsAvailableAsHResult() const
-  {
-    return true;
-  }
-
-  UniqueString AsString() const
-  {
-    LPWSTR rawMsgBuf = nullptr;
-    DWORD result = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                                    FORMAT_MESSAGE_FROM_SYSTEM |
-                                    FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
-                                    mHResult, 0,
-                                    reinterpret_cast<LPWSTR>(&rawMsgBuf), 0,
-                                    nullptr);
-    if (!result) {
-      return nullptr;
-    }
-
-    return UniqueString(rawMsgBuf);
-  }
-
-  HRESULT AsHResult() const
-  {
-    return mHResult;
-  }
-
-  // Not all HRESULTs are convertible to Win32 Errors, so we use Maybe
-  Maybe<DWORD> AsWin32Error() const
-  {
-    if (mHResult == S_OK) {
-      return Some(static_cast<DWORD>(ERROR_SUCCESS));
-    }
-
-    if (HRESULT_FACILITY(mHResult) == FACILITY_WIN32) {
-      // This is the inverse of HRESULT_FROM_WIN32
-      return Some(static_cast<DWORD>(HRESULT_CODE(mHResult)));
-    }
-
-    // The NTSTATUS facility is a special case and thus does not utilize the
-    // HRESULT_FACILITY and HRESULT_CODE macros.
-    if (mHResult & FACILITY_NT_BIT) {
-      return Some(NtStatusToWin32Error(
-        static_cast<NTSTATUS>(mHResult & ~FACILITY_NT_BIT)));
-    }
-
-    return Nothing();
-  }
-
-  // Not all HRESULTs are convertible to NTSTATUS, so we use Maybe
-  Maybe<NTSTATUS> AsNtStatus() const
-  {
-    if (mHResult == S_OK) {
-      return Some(STATUS_SUCCESS);
-    }
-
-    // The NTSTATUS facility is a special case and thus does not utilize the
-    // HRESULT_FACILITY and HRESULT_CODE macros.
-    if (mHResult & FACILITY_NT_BIT) {
-      return Some(static_cast<NTSTATUS>(mHResult & ~FACILITY_NT_BIT));
-    }
-
-    return Nothing();
-  }
-
-  static DWORD NtStatusToWin32Error(NTSTATUS aNtStatus)
-  {
-    static const DynamicallyLinkedFunctionPtr<decltype(&RtlNtStatusToDosError)>
-      pRtlNtStatusToDosError(L"ntdll.dll", "RtlNtStatusToDosError");
-
-    MOZ_ASSERT(!!pRtlNtStatusToDosError);
-    if (!pRtlNtStatusToDosError) {
-      return ERROR_UNIDENTIFIED_ERROR;
-    }
-
-    return pRtlNtStatusToDosError(aNtStatus);
-  }
-
-private:
-  // We store the error code as an HRESULT because they can encode both Win32
-  // error codes and NTSTATUS codes.
-  HRESULT mHResult;
-};
-
-template <typename T>
-using WindowsErrorResult = Result<T, WindowsError>;
-
 // How long to wait for a created process to become available for input,
 // to prevent that process's windows being forced to the background.
 // This is used across update, restart, and the launcher.
 const DWORD kWaitForInputIdleTimeoutMS = 10*1000;
 
 /**
  * Wait for a child GUI process to become "idle." Idle means that the process
  * has created its message queue and has begun waiting for user input.
@@ -238,122 +74,104 @@ WaitForInputIdle(HANDLE aProcess, DWORD 
       ::Sleep(kSleepTimeMs);
       continue;
     }
 
     return false;
   }
 }
 
-enum class PathType
-{
+enum PathType {
   eNtPath,
   eDosPath,
 };
 
 class FileUniqueId final
 {
 public:
   explicit FileUniqueId(const wchar_t* aPath, PathType aPathType)
     : mId()
   {
     if (!aPath) {
       return;
     }
 
-    nsAutoHandle file;
-
+    nsAutoHandle file(INVALID_HANDLE_VALUE);
     switch (aPathType) {
-      default:
-        MOZ_ASSERT_UNREACHABLE("Unhandled PathType");
-        return;
+    default:
+      return;
 
-      case PathType::eNtPath: {
-          UNICODE_STRING unicodeString;
-          ::RtlInitUnicodeString(&unicodeString, aPath);
-          OBJECT_ATTRIBUTES objectAttributes;
-          InitializeObjectAttributes(&objectAttributes, &unicodeString,
-                                     OBJ_CASE_INSENSITIVE, nullptr, nullptr);
-          IO_STATUS_BLOCK ioStatus = {};
-          HANDLE ntHandle;
-          NTSTATUS status = ::NtOpenFile(&ntHandle, SYNCHRONIZE |
-                                         FILE_READ_ATTRIBUTES,
-                                         &objectAttributes, &ioStatus,
-                                         FILE_SHARE_READ | FILE_SHARE_WRITE |
-                                         FILE_SHARE_DELETE,
-                                         FILE_SYNCHRONOUS_IO_NONALERT |
-                                         FILE_OPEN_FOR_BACKUP_INTENT);
-          // We don't need to check |ntHandle| for INVALID_HANDLE_VALUE here,
-          // as that value is set by the Win32 layer.
-          if (!NT_SUCCESS(status)) {
-            mError = Some(WindowsError::FromNtStatus(status));
-            return;
-          }
-
-          file.own(ntHandle);
-        }
-
-        break;
-
-      case PathType::eDosPath: {
-        file.own(::CreateFileW(aPath, 0, FILE_SHARE_READ |
-                               FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                               nullptr, OPEN_EXISTING,
-                               FILE_FLAG_BACKUP_SEMANTICS, nullptr));
-        if (file == INVALID_HANDLE_VALUE) {
-          mError = Some(WindowsError::FromLastError());
+    case eNtPath:
+      {
+        UNICODE_STRING unicodeString;
+        ::RtlInitUnicodeString(&unicodeString, aPath);
+        OBJECT_ATTRIBUTES objectAttributes;
+        InitializeObjectAttributes(&objectAttributes, &unicodeString,
+                                   OBJ_CASE_INSENSITIVE, nullptr, nullptr);
+        IO_STATUS_BLOCK ioStatus = {};
+        HANDLE ntHandle;
+        NTSTATUS status = ::NtOpenFile(&ntHandle, SYNCHRONIZE |
+                                       FILE_READ_ATTRIBUTES,
+                                       &objectAttributes, &ioStatus,
+                                       FILE_SHARE_READ | FILE_SHARE_WRITE |
+                                       FILE_SHARE_DELETE,
+                                       FILE_SYNCHRONOUS_IO_NONALERT |
+                                       FILE_OPEN_FOR_BACKUP_INTENT);
+        if (!NT_SUCCESS(status) || ntHandle == INVALID_HANDLE_VALUE) {
           return;
         }
+        file.own(ntHandle);
+      }
+      break;
 
-        break;
+    case eDosPath:
+      file.own(::CreateFileW(aPath, 0, FILE_SHARE_READ |
+                             FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                             nullptr, OPEN_EXISTING,
+                             FILE_FLAG_BACKUP_SEMANTICS, nullptr));
+      if (file == INVALID_HANDLE_VALUE) {
+        return;
       }
+      break;
     }
 
     GetId(file);
   }
 
   explicit FileUniqueId(const nsAutoHandle& aFile)
     : mId()
   {
     GetId(aFile);
   }
 
   FileUniqueId(const FileUniqueId& aOther)
     : mId(aOther.mId)
-    , mError(aOther.mError)
   {
   }
 
   ~FileUniqueId() = default;
 
   explicit operator bool() const
   {
     FILE_ID_INFO zeros = {};
-    return !mError && memcmp(&mId, &zeros, sizeof(FILE_ID_INFO));
-  }
-
-  Maybe<WindowsError> GetError() const
-  {
-    return mError;
+    return memcmp(&mId, &zeros, sizeof(FILE_ID_INFO));
   }
 
   FileUniqueId& operator=(const FileUniqueId& aOther)
   {
     mId = aOther.mId;
-    mError = aOther.mError;
     return *this;
   }
 
   FileUniqueId(FileUniqueId&& aOther) = delete;
   FileUniqueId& operator=(FileUniqueId&& aOther) = delete;
 
   bool operator==(const FileUniqueId& aOther) const
   {
-    return !mError && !aOther.mError &&
-           !memcmp(&mId, &aOther.mId, sizeof(FILE_ID_INFO));
+    return !memcmp(&mId, &aOther.mId, sizeof(FILE_ID_INFO));
   }
 
   bool operator!=(const FileUniqueId& aOther) const
   {
     return !((*this) == aOther);
   }
 
 private:
@@ -364,47 +182,43 @@ private:
         return;
       }
       // Only NTFS and ReFS support FileIdInfo. So we have to fallback if
       // GetFileInformationByHandleEx failed.
     }
 
     BY_HANDLE_FILE_INFORMATION info = {};
     if (!::GetFileInformationByHandle(aFile.get(), &info)) {
-      mError = Some(WindowsError::FromLastError());
       return;
     }
 
     mId.VolumeSerialNumber = info.dwVolumeSerialNumber;
     memcpy(&mId.FileId.Identifier[0], &info.nFileIndexLow,
            sizeof(DWORD));
     memcpy(&mId.FileId.Identifier[sizeof(DWORD)], &info.nFileIndexHigh,
            sizeof(DWORD));
   }
 
 private:
-  FILE_ID_INFO        mId;
-  Maybe<WindowsError> mError;
+  FILE_ID_INFO  mId;
 };
 
-inline WindowsErrorResult<bool>
+inline Maybe<bool>
 DoPathsPointToIdenticalFile(const wchar_t* aPath1, const wchar_t* aPath2,
-                            PathType aPathType1 = PathType::eDosPath,
-                            PathType aPathType2 = PathType::eDosPath)
+                            PathType aPathType1 = eDosPath,
+                            PathType aPathType2 = eDosPath)
 {
   FileUniqueId id1(aPath1, aPathType1);
   if (!id1) {
-    Maybe<WindowsError> error = id1.GetError();
-    return Err(error.valueOr(WindowsError::CreateGeneric()));
+    return Nothing();
   }
 
   FileUniqueId id2(aPath2, aPathType2);
   if (!id2) {
-    Maybe<WindowsError> error = id2.GetError();
-    return Err(error.valueOr(WindowsError::CreateGeneric()));
+    return Nothing();
   }
 
-  return id1 == id2;
+  return Some(id1 == id2);
 }
 
 } // namespace mozilla
 
 #endif // mozilla_WinHeaderOnlyUtils_h