Chromium Code Reviews| Index: chrome/browser/conflicts/module_info_win.cc |
| diff --git a/chrome/browser/conflicts/module_info_win.cc b/chrome/browser/conflicts/module_info_win.cc |
| index 3b82030e176ce752c0ab7c38f0420d9841cd78af..9c561b6d7801968805bc4c74b385b03d8f46260a 100644 |
| --- a/chrome/browser/conflicts/module_info_win.cc |
| +++ b/chrome/browser/conflicts/module_info_win.cc |
| @@ -4,6 +4,90 @@ |
| #include "chrome/browser/conflicts/module_info_win.h" |
| +#include <windows.h> |
| + |
| +#include <fileapi.h> |
| + |
| +#include <memory> |
| + |
| +#include "base/file_version_info.h" |
| +#include "base/i18n/case_conversion.h" |
| +#include "base/strings/string16.h" |
| +#include "base/strings/string_util.h" |
| + |
| +namespace { |
| + |
| +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.
|
| + ModuleInfoData* module_data) { |
| + module_data->location = key.module_path.value(); |
| + |
| + std::unique_ptr<FileVersionInfo> file_version_info( |
| + FileVersionInfo::CreateFileVersionInfo(key.module_path)); |
| + if (file_version_info) { |
| + module_data->product_name = file_version_info->product_name(); |
| + module_data->description = file_version_info->file_description(); |
| + module_data->version = file_version_info->product_version(); |
| + } |
| + |
| + GetCertificateInfo(key.module_path, &(module_data->certificate_info)); |
| +} |
| + |
| +// Returns the long path name given a short path name. A short path name is a |
| +// path that follows the 8.3 convention and has ~x in it. If the path is already |
| +// a long path name, the function returns the current path without modification. |
| +bool ConvertToLongPath(const base::string16& short_path, |
| + base::string16* long_path) { |
| + wchar_t long_path_buf[MAX_PATH]; |
| + DWORD return_value = |
| + ::GetLongPathName(short_path.c_str(), long_path_buf, MAX_PATH); |
| + if (return_value != 0 && return_value < MAX_PATH) { |
| + *long_path = long_path_buf; |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +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.
|
| + base::string16 path = module_data->location; |
| + if (!ConvertToLongPath(path, &module_data->location)) |
| + module_data->location = path; |
| + |
| + module_data->location = base::i18n::ToLower(module_data->location); |
| + |
| + // Location contains the filename, so the last slash is where the path |
| + // ends. |
| + size_t last_slash = module_data->location.find_last_of(L"\\"); |
| + if (last_slash != base::string16::npos) { |
| + module_data->basename = module_data->location.substr(last_slash + 1); |
| + module_data->location = module_data->location.substr(0, last_slash + 1); |
| + } else { |
| + module_data->basename = module_data->location; |
| + module_data->location.clear(); |
| + } |
| + |
| + // Some version strings use ", " instead ".". Convert those. |
| + base::ReplaceSubstringsAfterOffset(&module_data->version, 0, L", ", L"."); |
| + |
| + // Some version strings have things like (win7_rtm.090713-1255) appended |
| + // to them. Remove that. |
| + size_t first_space = module_data->version.find_first_of(L" "); |
| + if (first_space != base::string16::npos) |
| + module_data->version = module_data->version.substr(0, first_space); |
| + |
| + // The signer may be returned with trailing nulls. |
| + size_t first_null = module_data->certificate_info.subject.find(L'\0'); |
| + if (first_null != base::string16::npos) |
| + module_data->certificate_info.subject.resize(first_null); |
| +} |
| + |
| +void CollapsePath(const StringMapping& env_variable_mapping, |
| + ModuleInfoData* module_data) { |
| + CollapseMatchingPrefixInString(env_variable_mapping, &module_data->location); |
| +} |
| + |
| +} // namespace |
| + |
| // ModuleInfoKey --------------------------------------------------------------- |
| ModuleInfoKey::ModuleInfoKey(const base::FilePath& module_path, |
| @@ -26,8 +110,36 @@ bool ModuleInfoKey::operator<(const ModuleInfoKey& mik) const { |
| // ModuleInfoData -------------------------------------------------------------- |
| -ModuleInfoData::ModuleInfoData() : process_types(0) {} |
| +ModuleInfoData::ModuleInfoData() : process_types(0), inspected(false) {} |
| ModuleInfoData::ModuleInfoData(const ModuleInfoData& others) = default; |
| ModuleInfoData::~ModuleInfoData() = default; |
| + |
| +void ModuleInfoData::CopyInspectionData(const ModuleInfoData& other) { |
| + DCHECK(!inspected); |
| + |
| + // Copy every field that was populated by InspectModule(). |
| + inspected = other.inspected; |
| + location = other.location; |
| + basename = other.basename; |
| + product_name = other.product_name; |
| + description = other.description; |
| + version = other.version; |
| + certificate_info = other.certificate_info; |
| +} |
| + |
| +// ----------------------------------------------------------------------------- |
| + |
| +ModuleInfoData InspectModule(const StringMapping& env_variable_mapping, |
| + const ModuleInfoKey& module_key) { |
| + ModuleInfoData module_data; |
| + |
| + module_data.inspected = true; |
| + |
| + PopulateModuleInfoData(module_key, &module_data); |
| + NormalizeModuleInfoData(&module_data); |
| + CollapsePath(env_variable_mapping, &module_data); |
| + |
| + return module_data; |
| +} |