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