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