| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/conflicts/module_info_win.h" | 5 #include "chrome/browser/conflicts/module_info_win.h" |
| 6 | 6 |
| 7 #include <windows.h> |
| 8 |
| 9 #include <fileapi.h> |
| 10 |
| 11 #include <memory> |
| 12 |
| 13 #include "base/file_version_info.h" |
| 14 #include "base/i18n/case_conversion.h" |
| 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/strings/string16.h" |
| 17 #include "base/strings/string_util.h" |
| 18 |
| 19 namespace { |
| 20 |
| 21 // Using the module path, populates |inspection_result| with information |
| 22 // available via the file on disk. For example, this includes the description |
| 23 // and the certificate information. |
| 24 void PopulateModuleInfoData(const ModuleInfoKey& key, |
| 25 ModuleInspectionResult* inspection_result) { |
| 26 inspection_result->location = key.module_path.value(); |
| 27 |
| 28 std::unique_ptr<FileVersionInfo> file_version_info( |
| 29 FileVersionInfo::CreateFileVersionInfo(key.module_path)); |
| 30 if (file_version_info) { |
| 31 inspection_result->product_name = file_version_info->product_name(); |
| 32 inspection_result->description = file_version_info->file_description(); |
| 33 inspection_result->version = file_version_info->product_version(); |
| 34 } |
| 35 |
| 36 GetCertificateInfo(key.module_path, &(inspection_result->certificate_info)); |
| 37 } |
| 38 |
| 39 // Returns the long path name given a short path name. A short path name is a |
| 40 // path that follows the 8.3 convention and has ~x in it. If the path is already |
| 41 // a long path name, the function returns the current path without modification. |
| 42 bool ConvertToLongPath(const base::string16& short_path, |
| 43 base::string16* long_path) { |
| 44 wchar_t long_path_buf[MAX_PATH]; |
| 45 DWORD return_value = |
| 46 ::GetLongPathName(short_path.c_str(), long_path_buf, MAX_PATH); |
| 47 if (return_value != 0 && return_value < MAX_PATH) { |
| 48 *long_path = long_path_buf; |
| 49 return true; |
| 50 } |
| 51 |
| 52 return false; |
| 53 } |
| 54 |
| 55 } // namespace |
| 56 |
| 7 // ModuleInfoKey --------------------------------------------------------------- | 57 // ModuleInfoKey --------------------------------------------------------------- |
| 8 | 58 |
| 9 ModuleInfoKey::ModuleInfoKey(const base::FilePath& module_path, | 59 ModuleInfoKey::ModuleInfoKey(const base::FilePath& module_path, |
| 10 uint32_t module_size, | 60 uint32_t module_size, |
| 11 uint32_t module_time_date_stamp, | 61 uint32_t module_time_date_stamp, |
| 12 uint32_t module_id) | 62 uint32_t module_id) |
| 13 : module_path(module_path), | 63 : module_path(module_path), |
| 14 module_size(module_size), | 64 module_size(module_size), |
| 15 module_time_date_stamp(module_time_date_stamp), | 65 module_time_date_stamp(module_time_date_stamp), |
| 16 module_id(module_id) {} | 66 module_id(module_id) {} |
| 17 | 67 |
| 18 bool ModuleInfoKey::operator<(const ModuleInfoKey& mik) const { | 68 bool ModuleInfoKey::operator<(const ModuleInfoKey& mik) const { |
| 19 // The key consists of the triplet of | 69 // The key consists of the triplet of |
| 20 // (module_path, module_size, module_time_date_stamp). | 70 // (module_path, module_size, module_time_date_stamp). |
| 21 // Use the std::tuple lexicographic comparison operator. | 71 // Use the std::tuple lexicographic comparison operator. |
| 22 return std::make_tuple(module_path, module_size, module_time_date_stamp) < | 72 return std::make_tuple(module_path, module_size, module_time_date_stamp) < |
| 23 std::make_tuple(mik.module_path, mik.module_size, | 73 std::make_tuple(mik.module_path, mik.module_size, |
| 24 mik.module_time_date_stamp); | 74 mik.module_time_date_stamp); |
| 25 } | 75 } |
| 26 | 76 |
| 77 // ModuleInspectionResult ------------------------------------------------------ |
| 78 ModuleInspectionResult::ModuleInspectionResult() = default; |
| 79 |
| 80 ModuleInspectionResult::~ModuleInspectionResult() = default; |
| 81 |
| 27 // ModuleInfoData -------------------------------------------------------------- | 82 // ModuleInfoData -------------------------------------------------------------- |
| 28 | 83 |
| 29 ModuleInfoData::ModuleInfoData() : process_types(0) {} | 84 ModuleInfoData::ModuleInfoData() : process_types(0) {} |
| 30 | 85 |
| 31 ModuleInfoData::ModuleInfoData(const ModuleInfoData& others) = default; | 86 ModuleInfoData::~ModuleInfoData() = default; |
| 32 | 87 |
| 33 ModuleInfoData::~ModuleInfoData() = default; | 88 // ----------------------------------------------------------------------------- |
| 89 |
| 90 std::unique_ptr<ModuleInspectionResult> InspectModule( |
| 91 const StringMapping& env_variable_mapping, |
| 92 const ModuleInfoKey& module_key) { |
| 93 auto inspection_result = base::MakeUnique<ModuleInspectionResult>(); |
| 94 |
| 95 PopulateModuleInfoData(module_key, inspection_result.get()); |
| 96 internal::NormalizeInspectionResult(inspection_result.get()); |
| 97 CollapseMatchingPrefixInPath(env_variable_mapping, |
| 98 &inspection_result->location); |
| 99 |
| 100 return inspection_result; |
| 101 } |
| 102 |
| 103 namespace internal { |
| 104 |
| 105 void NormalizeInspectionResult(ModuleInspectionResult* inspection_result) { |
| 106 base::string16 path = inspection_result->location; |
| 107 if (!ConvertToLongPath(path, &inspection_result->location)) |
| 108 inspection_result->location = path; |
| 109 |
| 110 inspection_result->location = |
| 111 base::i18n::ToLower(inspection_result->location); |
| 112 |
| 113 // Location contains the filename, so the last slash is where the path |
| 114 // ends. |
| 115 size_t last_slash = inspection_result->location.find_last_of(L"\\"); |
| 116 if (last_slash != base::string16::npos) { |
| 117 inspection_result->basename = |
| 118 inspection_result->location.substr(last_slash + 1); |
| 119 inspection_result->location = |
| 120 inspection_result->location.substr(0, last_slash + 1); |
| 121 } else { |
| 122 inspection_result->basename = inspection_result->location; |
| 123 inspection_result->location.clear(); |
| 124 } |
| 125 |
| 126 // Some version strings use ", " instead ".". Convert those. |
| 127 base::ReplaceSubstringsAfterOffset(&inspection_result->version, 0, L", ", |
| 128 L"."); |
| 129 |
| 130 // Some version strings have things like (win7_rtm.090713-1255) appended |
| 131 // to them. Remove that. |
| 132 size_t first_space = inspection_result->version.find_first_of(L" "); |
| 133 if (first_space != base::string16::npos) |
| 134 inspection_result->version = |
| 135 inspection_result->version.substr(0, first_space); |
| 136 |
| 137 // The signer may be returned with trailing nulls. |
| 138 size_t first_null = inspection_result->certificate_info.subject.find(L'\0'); |
| 139 if (first_null != base::string16::npos) |
| 140 inspection_result->certificate_info.subject.resize(first_null); |
| 141 } |
| 142 |
| 143 } // namespace internal |
| OLD | NEW |