| 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..1d12f551469fdd5e7b8b0f826737de777125e919 100644
|
| --- a/chrome/browser/conflicts/module_info_win.cc
|
| +++ b/chrome/browser/conflicts/module_info_win.cc
|
| @@ -4,6 +4,60 @@
|
|
|
| #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 {
|
| +
|
| +// Using the module path, populates |module_data| with information available via
|
| +// the file on disk. For example, this includes the description and the
|
| +// certificate information.
|
| +void PopulateModuleInfoData(const ModuleInfoKey& key,
|
| + 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 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 +80,73 @@ 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);
|
| + internal::NormalizeModuleInfoData(&module_data);
|
| + CollapsePath(env_variable_mapping, &module_data);
|
| +
|
| + return module_data;
|
| +}
|
| +
|
| +namespace internal {
|
| +
|
| +void NormalizeModuleInfoData(ModuleInfoData* module_data) {
|
| + 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);
|
| +}
|
| +
|
| +} // namespace internal
|
|
|