Bug 1496387 - Avoid changing the path format back and forth in order to reduce possibility of failures. r=mhowell
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Fri, 05 Oct 2018 22:30:37 +0900
changeset 495660 0db58037928d28a7b6eab44c94c5be3ac6b23b6d
parent 495659 6b1761e269846b394b18979fc86264f8cea81610
child 495661 9f2c6ae03c6d5cab74ec0965002edc5776911748
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhowell
bugs1496387
milestone64.0a1
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
Bug 1496387 - Avoid changing the path format back and forth in order to reduce possibility of failures. r=mhowell QueryFullProcessImageNameW may fail in some environments when dwFlags is zero due to NT-to-DOS path conversions. CreateFile will convert the argumant back to an NT path anyway.
browser/app/winlauncher/LauncherProcessWin.cpp
widget/windows/WinHeaderOnlyUtils.h
--- a/browser/app/winlauncher/LauncherProcessWin.cpp
+++ b/browser/app/winlauncher/LauncherProcessWin.cpp
@@ -183,34 +183,35 @@ IsSameBinaryAsParentProcess()
     // 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(), 0, parentExe,
-                                    &parentExeLen)) {
+  if (!::QueryFullProcessImageNameW(parentProcess.get(), PROCESS_NAME_NATIVE,
+                                    parentExe, &parentExeLen)) {
     // 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)) {
     // If GetModuleFileNameW failed, we should not behave as the launcher
     // process for the same reason as NtQueryInformationProcess.
     MOZ_CRASH("GetModuleFileNameW failed");
   }
 
   mozilla::Maybe<bool> isSame =
-    mozilla::DoPathsPointToIdenticalFile(parentExe, ourExe);
+    mozilla::DoPathsPointToIdenticalFile(parentExe, ourExe,
+                                         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.value();
 }
 
--- a/widget/windows/WinHeaderOnlyUtils.h
+++ b/widget/windows/WinHeaderOnlyUtils.h
@@ -3,16 +3,17 @@
 /* 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 <winternl.h>
 
 #include "mozilla/Maybe.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
@@ -73,32 +74,68 @@ WaitForInputIdle(HANDLE aProcess, DWORD 
       ::Sleep(kSleepTimeMs);
       continue;
     }
 
     return false;
   }
 }
 
+enum PathType {
+  eNtPath,
+  eDosPath,
+};
+
 class FileUniqueId final
 {
 public:
-  explicit FileUniqueId(const wchar_t* aPath)
+  explicit FileUniqueId(const wchar_t* aPath, PathType aPathType)
     : mId()
   {
     if (!aPath) {
       return;
     }
 
-    nsAutoHandle file(::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) {
+    nsAutoHandle file(INVALID_HANDLE_VALUE);
+    switch (aPathType) {
+    default:
       return;
+
+    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;
+
+    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()
   {
@@ -160,24 +197,26 @@ private:
            sizeof(DWORD));
   }
 
 private:
   FILE_ID_INFO  mId;
 };
 
 inline Maybe<bool>
-DoPathsPointToIdenticalFile(const wchar_t* aPath1, const wchar_t* aPath2)
+DoPathsPointToIdenticalFile(const wchar_t* aPath1, const wchar_t* aPath2,
+                            PathType aPathType1 = eDosPath,
+                            PathType aPathType2 = eDosPath)
 {
-  FileUniqueId id1(aPath1);
+  FileUniqueId id1(aPath1, aPathType1);
   if (!id1) {
     return Nothing();
   }
 
-  FileUniqueId id2(aPath2);
+  FileUniqueId id2(aPath2, aPathType2);
   if (!id2) {
     return Nothing();
   }
 
   return Some(id1 == id2);
 }
 
 } // namespace mozilla