Add a InspectModule() function to the UtilWin interface

This function does the same as InspectModule() in
chrome/browser/conflicts/module_info_win.cc but runs out of process.

Bug: 921746
Change-Id: I6aaf919741ac253f5666f57bf199aabb5e4331b2
Reviewed-on: https://chromium-review.googlesource.com/c/1415763
Commit-Queue: Patrick Monette <pmonette@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#624684}
diff --git a/chrome/services/util_win/BUILD.gn b/chrome/services/util_win/BUILD.gn
index 46752dfd..ece9d3d 100644
--- a/chrome/services/util_win/BUILD.gn
+++ b/chrome/services/util_win/BUILD.gn
@@ -14,6 +14,7 @@
 
   deps = [
     "//base",
+    "//chrome/browser/conflicts:module_info",
     "//mojo/public/cpp/bindings",
   ]
 
diff --git a/chrome/services/util_win/DEPS b/chrome/services/util_win/DEPS
index b3447e4..588922d0 100644
--- a/chrome/services/util_win/DEPS
+++ b/chrome/services/util_win/DEPS
@@ -1,4 +1,6 @@
 include_rules = [
+  "+chrome/browser/conflicts/module_info_util_win.h",
+  "+chrome/browser/conflicts/module_info_win.h",
   "+chrome/installer/util/install_util.h",
   "+content/public/utility/utility_thread.h",
 ]
diff --git a/chrome/services/util_win/public/mojom/util_win.mojom b/chrome/services/util_win/public/mojom/util_win.mojom
index b2876b4..cb990d58 100644
--- a/chrome/services/util_win/public/mojom/util_win.mojom
+++ b/chrome/services/util_win/public/mojom/util_win.mojom
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Utility process interface exposed to the browser process on OS_WIN, for
-// calling OS_WIN task pinning and file open/save dialog API.
-
 module chrome.mojom;
 
 import "mojo/public/mojom/base/file_path.mojom";
@@ -38,6 +35,41 @@
   mojo_base.mojom.String16 extension_spec;
 };
 
+enum CertificateType {
+  // The module is not signed.
+  kNoCertificate,
+  // The module is signed and the certificate is in the module.
+  kCertificateInFile,
+  // The module is signed and the certificate is in an external catalog.
+  kCertificateInCatalog,
+};
+
+struct InspectionResult {
+  // The lowercase module path, not including the basename.
+  mojo_base.mojom.String16 location;
+  // The basename of the module.
+  mojo_base.mojom.String16 basename;
+  // The name of the product the module belongs to.
+  mojo_base.mojom.String16 product_name;
+  // The module file description.
+  mojo_base.mojom.String16 description;
+  // The module version. This is usually in the form a.b.c.d (where a, b, c and
+  // d are integers), but may also have fewer than 4 components.
+  mojo_base.mojom.String16 version;
+  // The type of the certificate for this module.
+  CertificateType certificate_type;
+  // Path to the file containing the certificate. Empty if |certificate_type| is
+  // kNoCertificate.
+  mojo_base.mojom.FilePath certificate_path;
+  // The "Subject" name of the certificate. This is the signer (ie,
+  // "Google Inc." or "Microsoft Inc.").
+  mojo_base.mojom.String16 certificate_subject;
+};
+
+// Utility process interface exposed to the browser process on OS_WIN. Used to
+// improve stability by executing some tasks out-of-process. This include either
+// crashy tasks, or tasks that requires certain DLLs to be loaded into the
+// process address space that we don't want to load in the main process.
 interface UtilWin {
   // Returns the pinned state of the current executable.
   IsPinnedToTaskbar() => (bool succeeded, bool is_pinned_to_taskbar);
@@ -72,4 +104,10 @@
                         mojo_base.mojom.String16 default_extension) =>
       (array<mojo_base.mojom.FilePath> paths,
        int32 file_type_index);
+
+  // Given a module located at |module_path|, returns a populated
+  // ModuleInspectionResult that contains detailed information about the module
+  // on disk.
+  InspectModule(mojo_base.mojom.FilePath module_path) =>
+      (InspectionResult inspection_result);
 };
diff --git a/chrome/services/util_win/public/mojom/util_win.typemap b/chrome/services/util_win/public/mojom/util_win.typemap
index 304ec85..45c5526 100644
--- a/chrome/services/util_win/public/mojom/util_win.typemap
+++ b/chrome/services/util_win/public/mojom/util_win.typemap
@@ -5,7 +5,10 @@
 mojom = "//chrome/services/util_win/public/mojom/util_win.mojom"
 
 public_headers = [
+  "//base/files/file_path.h",
   "//base/strings/string16.h",
+  "//chrome/browser/conflicts/module_info_util_win.h",
+  "//chrome/browser/conflicts/module_info_win.h",
   "//ui/shell_dialogs/execute_select_file_win.h",
   "//ui/shell_dialogs/select_file_dialog.h",
 ]
@@ -19,10 +22,13 @@
 
 deps = [
   "//base",
+  "//chrome/browser/conflicts:module_info",
   "//ui/shell_dialogs",
 ]
 
 type_mappings = [
+  "chrome.mojom.CertificateType=CertificateInfo::Type",
   "chrome.mojom.FileFilterSpec=ui::FileFilterSpec",
+  "chrome.mojom.InspectionResult=ModuleInspectionResult[move_only]",
   "chrome.mojom.SelectFileDialogType=ui::SelectFileDialog::Type",
 ]
diff --git a/chrome/services/util_win/public/mojom/util_win_mojom_traits.cc b/chrome/services/util_win/public/mojom/util_win_mojom_traits.cc
index fb42ab7..a4acd3d 100644
--- a/chrome/services/util_win/public/mojom/util_win_mojom_traits.cc
+++ b/chrome/services/util_win/public/mojom/util_win_mojom_traits.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/services/util_win/public/mojom/util_win_mojom_traits.h"
 
+#include "mojo/public/cpp/base/file_path_mojom_traits.h"
 #include "mojo/public/cpp/base/string16_mojom_traits.h"
 
 namespace mojo {
@@ -65,6 +66,108 @@
 }
 
 // static
+chrome::mojom::CertificateType
+EnumTraits<chrome::mojom::CertificateType, CertificateInfo::Type>::ToMojom(
+    CertificateInfo::Type input) {
+  switch (input) {
+    case CertificateInfo::Type::NO_CERTIFICATE:
+      return chrome::mojom::CertificateType::kNoCertificate;
+    case CertificateInfo::Type::CERTIFICATE_IN_FILE:
+      return chrome::mojom::CertificateType::kCertificateInFile;
+    case CertificateInfo::Type::CERTIFICATE_IN_CATALOG:
+      return chrome::mojom::CertificateType::kCertificateInCatalog;
+  }
+  NOTREACHED();
+  return chrome::mojom::CertificateType::kNoCertificate;
+}
+
+// static
+bool EnumTraits<chrome::mojom::CertificateType, CertificateInfo::Type>::
+    FromMojom(chrome::mojom::CertificateType input,
+              CertificateInfo::Type* output) {
+  switch (input) {
+    case chrome::mojom::CertificateType::kNoCertificate:
+      *output = CertificateInfo::Type::NO_CERTIFICATE;
+      return true;
+    case chrome::mojom::CertificateType::kCertificateInFile:
+      *output = CertificateInfo::Type::CERTIFICATE_IN_FILE;
+      return true;
+    case chrome::mojom::CertificateType::kCertificateInCatalog:
+      *output = CertificateInfo::Type::CERTIFICATE_IN_CATALOG;
+      return true;
+  }
+
+  NOTREACHED();
+  return false;
+}
+
+// static
+const base::string16& StructTraits<
+    chrome::mojom::InspectionResultDataView,
+    ModuleInspectionResult>::location(const ModuleInspectionResult& input) {
+  return input.location;
+}
+// static
+const base::string16& StructTraits<
+    chrome::mojom::InspectionResultDataView,
+    ModuleInspectionResult>::basename(const ModuleInspectionResult& input) {
+  return input.basename;
+}
+// static
+const base::string16& StructTraits<
+    chrome::mojom::InspectionResultDataView,
+    ModuleInspectionResult>::product_name(const ModuleInspectionResult& input) {
+  return input.product_name;
+}
+// static
+const base::string16& StructTraits<
+    chrome::mojom::InspectionResultDataView,
+    ModuleInspectionResult>::description(const ModuleInspectionResult& input) {
+  return input.description;
+}
+// static
+const base::string16& StructTraits<
+    chrome::mojom::InspectionResultDataView,
+    ModuleInspectionResult>::version(const ModuleInspectionResult& input) {
+  return input.basename;
+}
+// static
+chrome::mojom::CertificateType
+StructTraits<chrome::mojom::InspectionResultDataView, ModuleInspectionResult>::
+    certificate_type(const ModuleInspectionResult& input) {
+  return EnumTraits<chrome::mojom::CertificateType,
+                    CertificateInfo::Type>::ToMojom(input.certificate_info
+                                                        .type);
+}
+// static
+const base::FilePath&
+StructTraits<chrome::mojom::InspectionResultDataView, ModuleInspectionResult>::
+    certificate_path(const ModuleInspectionResult& input) {
+  return input.certificate_info.path;
+}
+// static
+const base::string16&
+StructTraits<chrome::mojom::InspectionResultDataView, ModuleInspectionResult>::
+    certificate_subject(const ModuleInspectionResult& input) {
+  return input.certificate_info.subject;
+}
+
+// static
+bool StructTraits<
+    chrome::mojom::InspectionResultDataView,
+    ModuleInspectionResult>::Read(chrome::mojom::InspectionResultDataView input,
+                                  ModuleInspectionResult* out) {
+  return input.ReadLocation(&out->location) &&
+         input.ReadBasename(&out->basename) &&
+         input.ReadProductName(&out->product_name) &&
+         input.ReadDescription(&out->description) &&
+         input.ReadVersion(&out->version) &&
+         input.ReadCertificateType(&out->certificate_info.type) &&
+         input.ReadCertificatePath(&out->certificate_info.path) &&
+         input.ReadCertificateSubject(&out->certificate_info.subject);
+}
+
+// static
 bool StructTraits<chrome::mojom::FileFilterSpecDataView, ui::FileFilterSpec>::
     Read(chrome::mojom::FileFilterSpecDataView input, ui::FileFilterSpec* out) {
   return input.ReadDescription(&out->description) &&
diff --git a/chrome/services/util_win/public/mojom/util_win_mojom_traits.h b/chrome/services/util_win/public/mojom/util_win_mojom_traits.h
index 0b35a3c..51af58e 100644
--- a/chrome/services/util_win/public/mojom/util_win_mojom_traits.h
+++ b/chrome/services/util_win/public/mojom/util_win_mojom_traits.h
@@ -5,7 +5,10 @@
 #ifndef CHROME_SERVICES_UTIL_WIN_PUBLIC_MOJOM_UTIL_WIN_MOJOM_TRAITS_H_
 #define CHROME_SERVICES_UTIL_WIN_PUBLIC_MOJOM_UTIL_WIN_MOJOM_TRAITS_H_
 
+#include "base/files/file_path.h"
 #include "base/strings/string16.h"
+#include "chrome/browser/conflicts/module_info_util_win.h"
+#include "chrome/browser/conflicts/module_info_win.h"
 #include "chrome/services/util_win/public/mojom/util_win.mojom.h"
 #include "ui/shell_dialogs/execute_select_file_win.h"
 
@@ -21,6 +24,33 @@
 };
 
 template <>
+struct EnumTraits<chrome::mojom::CertificateType, CertificateInfo::Type> {
+  static chrome::mojom::CertificateType ToMojom(CertificateInfo::Type input);
+  static bool FromMojom(chrome::mojom::CertificateType input,
+                        CertificateInfo::Type* output);
+};
+
+template <>
+struct StructTraits<chrome::mojom::InspectionResultDataView,
+                    ModuleInspectionResult> {
+  static const base::string16& location(const ModuleInspectionResult& input);
+  static const base::string16& basename(const ModuleInspectionResult& input);
+  static const base::string16& product_name(
+      const ModuleInspectionResult& input);
+  static const base::string16& description(const ModuleInspectionResult& input);
+  static const base::string16& version(const ModuleInspectionResult& input);
+  static chrome::mojom::CertificateType certificate_type(
+      const ModuleInspectionResult& input);
+  static const base::FilePath& certificate_path(
+      const ModuleInspectionResult& input);
+  static const base::string16& certificate_subject(
+      const ModuleInspectionResult& input);
+
+  static bool Read(chrome::mojom::InspectionResultDataView data,
+                   ModuleInspectionResult* output);
+};
+
+template <>
 struct StructTraits<chrome::mojom::FileFilterSpecDataView, ui::FileFilterSpec> {
   static const base::string16& description(const ui::FileFilterSpec& input) {
     return input.description;
diff --git a/chrome/services/util_win/util_win_impl.cc b/chrome/services/util_win/util_win_impl.cc
index d9c1023b..05a2c15 100644
--- a/chrome/services/util_win/util_win_impl.cc
+++ b/chrome/services/util_win/util_win_impl.cc
@@ -20,6 +20,7 @@
 #include "base/win/scoped_variant.h"
 #include "base/win/shortcut.h"
 #include "base/win/win_util.h"
+#include "chrome/browser/conflicts/module_info_util_win.h"
 #include "chrome/installer/util/install_util.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "ui/shell_dialogs/execute_select_file_win.h"
@@ -243,3 +244,8 @@
       reinterpret_cast<HWND>(base::win::Uint32ToHandle(owner)),
       base::BindOnce(std::move(callback)));
 }
+
+void UtilWinImpl::InspectModule(const base::FilePath& module_path,
+                                InspectModuleCallback callback) {
+  std::move(callback).Run(::InspectModule(module_path));
+}
diff --git a/chrome/services/util_win/util_win_impl.h b/chrome/services/util_win/util_win_impl.h
index e85cfe4..300ccaf8 100644
--- a/chrome/services/util_win/util_win_impl.h
+++ b/chrome/services/util_win/util_win_impl.h
@@ -31,6 +31,8 @@
                              int32_t file_type_index,
                              const base::string16& default_extension,
                              CallExecuteSelectFileCallback callback) override;
+  void InspectModule(const base::FilePath& module_path,
+                     InspectModuleCallback callback) override;
 
   const std::unique_ptr<service_manager::ServiceContextRef> service_ref_;