diff --git a/snapshot/win/module_snapshot_win.cc b/snapshot/win/module_snapshot_win.cc index c3f915f8..77a8e037 100644 --- a/snapshot/win/module_snapshot_win.cc +++ b/snapshot/win/module_snapshot_win.cc @@ -18,6 +18,7 @@ #include "snapshot/win/pe_image_reader.h" #include "util/misc/tri_state.h" #include "util/misc/uuid.h" +#include "util/win/module_version.h" namespace crashpad { namespace internal { @@ -39,13 +40,13 @@ bool ModuleSnapshotWin::Initialize( INITIALIZATION_STATE_SET_INITIALIZING(initialized_); process_reader_ = process_reader; - name_ = base::UTF16ToUTF8(process_reader_module.name); + name_ = process_reader_module.name; timestamp_ = process_reader_module.timestamp; pe_image_reader_.reset(new PEImageReader()); if (!pe_image_reader_->Initialize(process_reader_, process_reader_module.dll_base, process_reader_module.size, - name_)) { + base::UTF16ToUTF8(name_))) { return false; } @@ -74,7 +75,7 @@ void ModuleSnapshotWin::GetCrashpadOptions(CrashpadInfoClientOptions* options) { std::string ModuleSnapshotWin::Name() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return name_; + return base::UTF16ToUTF8(name_); } uint64_t ModuleSnapshotWin::Address() const { @@ -97,7 +98,18 @@ void ModuleSnapshotWin::FileVersion(uint16_t* version_0, uint16_t* version_2, uint16_t* version_3) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - CHECK(false) << "TODO(scottmg)"; + VS_FIXEDFILEINFO ffi; + if (GetModuleVersionAndType(base::FilePath(name_), &ffi)) { + *version_0 = ffi.dwFileVersionMS >> 16; + *version_1 = ffi.dwFileVersionMS & 0xffff; + *version_2 = ffi.dwFileVersionLS >> 16; + *version_3 = ffi.dwFileVersionLS & 0xffff; + } else { + *version_0 = 0; + *version_1 = 0; + *version_2 = 0; + *version_3 = 0; + } } void ModuleSnapshotWin::SourceVersion(uint16_t* version_0, @@ -105,13 +117,32 @@ void ModuleSnapshotWin::SourceVersion(uint16_t* version_0, uint16_t* version_2, uint16_t* version_3) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - CHECK(false) << "TODO(scottmg)"; + VS_FIXEDFILEINFO ffi; + if (GetModuleVersionAndType(base::FilePath(name_), &ffi)) { + *version_0 = ffi.dwProductVersionMS >> 16; + *version_1 = ffi.dwProductVersionMS & 0xffff; + *version_2 = ffi.dwProductVersionLS >> 16; + *version_3 = ffi.dwProductVersionLS & 0xffff; + } else { + *version_0 = 0; + *version_1 = 0; + *version_2 = 0; + *version_3 = 0; + } } ModuleSnapshot::ModuleType ModuleSnapshotWin::GetModuleType() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - CHECK(false) << "TODO(scottmg)"; - return ModuleSnapshot::ModuleType(); + VS_FIXEDFILEINFO ffi; + if (GetModuleVersionAndType(base::FilePath(name_), &ffi)) { + if (ffi.dwFileType == VFT_APP) + return ModuleSnapshot::kModuleTypeExecutable; + if (ffi.dwFileType == VFT_DLL) + return ModuleSnapshot::kModuleTypeSharedLibrary; + if (ffi.dwFileType == VFT_DRV || ffi.dwFileType == VFT_VXD) + return ModuleSnapshot::kModuleTypeLoadableModule; + } + return ModuleSnapshot::kModuleTypeUnknown; } void ModuleSnapshotWin::UUID(crashpad::UUID* uuid) const { diff --git a/snapshot/win/module_snapshot_win.h b/snapshot/win/module_snapshot_win.h index a25659d1..d3ea671c 100644 --- a/snapshot/win/module_snapshot_win.h +++ b/snapshot/win/module_snapshot_win.h @@ -81,7 +81,7 @@ class ModuleSnapshotWin final : public ModuleSnapshot { std::map AnnotationsSimpleMap() const override; private: - std::string name_; + std::wstring name_; time_t timestamp_; scoped_ptr pe_image_reader_; ProcessReaderWin* process_reader_; // weak diff --git a/snapshot/win/system_snapshot_win.cc b/snapshot/win/system_snapshot_win.cc index 5e24211a..a7523f48 100644 --- a/snapshot/win/system_snapshot_win.cc +++ b/snapshot/win/system_snapshot_win.cc @@ -23,10 +23,10 @@ #include #include -#include "base/memory/scoped_ptr.h" #include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "util/win/module_version.h" namespace crashpad { @@ -95,45 +95,25 @@ void SystemSnapshotWin::Initialize(ProcessReaderWin* process_reader) { PLOG(WARNING) << "GetVersionEx"; } else { const wchar_t kSystemDll[] = L"kernel32.dll"; - DWORD size = GetFileVersionInfoSize(kSystemDll, nullptr); - if (!size) { - PLOG(WARNING) << "GetFileVersionInfoSize"; - } else { - scoped_ptr data(new uint8_t[size]); - if (!GetFileVersionInfo(kSystemDll, 0, size, data.get())) { - PLOG(WARNING) << "GetFileVersionInfo"; - } else { - VS_FIXEDFILEINFO* fixed_file_info; - UINT size; - if (!VerQueryValue(data.get(), - L"\\", - reinterpret_cast(&fixed_file_info), - &size)) { - PLOG(WARNING) << "VerQueryValue"; - } else { - uint32_t valid_flags = - fixed_file_info->dwFileFlags & fixed_file_info->dwFileFlagsMask; - std::string flags_string = GetStringForFileFlags(valid_flags); - os_version_major_ = - (fixed_file_info->dwFileVersionMS & 0xffff0000) >> 16; - os_version_minor_ = fixed_file_info->dwFileVersionMS & 0xffff; - os_version_bugfix_ = - (fixed_file_info->dwFileVersionLS & 0xffff0000) >> 16; - os_version_build_ = base::StringPrintf( - "%d", fixed_file_info->dwFileVersionLS & 0xffff); - os_server_ = version_info.wProductType != VER_NT_WORKSTATION; - std::string os_name = GetStringForFileOS(fixed_file_info->dwFileOS); - os_version_full_ = base::StringPrintf( - "%s %d.%d.%d.%s%s", - os_name.c_str(), - os_version_major_, - os_version_minor_, - os_version_bugfix_, - os_version_build_.c_str(), - flags_string.empty() ? "" : (std::string(" (") + flags_string + - ")").c_str()); - } - } + VS_FIXEDFILEINFO ffi; + if (GetModuleVersionAndType(base::FilePath(kSystemDll), &ffi)) { + std::string flags_string = GetStringForFileFlags(ffi.dwFileFlags); + os_server_ = version_info.wProductType != VER_NT_WORKSTATION; + std::string os_name = GetStringForFileOS(ffi.dwFileOS); + os_version_major_ = ffi.dwFileVersionMS >> 16; + os_version_minor_ = ffi.dwFileVersionMS & 0xffff; + os_version_bugfix_ = ffi.dwFileVersionLS >> 16; + os_version_build_ = + base::StringPrintf("%d", ffi.dwFileVersionLS & 0xffff); + os_version_full_ = base::StringPrintf( + "%s %d.%d.%d.%s%s", + os_name.c_str(), + os_version_major_, + os_version_minor_, + os_version_bugfix_, + os_version_build_.c_str(), + flags_string.empty() ? "" : (std::string(" (") + flags_string + ")") + .c_str()); } } diff --git a/util/util.gyp b/util/util.gyp index 3bfa2585..b93e1667 100644 --- a/util/util.gyp +++ b/util/util.gyp @@ -147,6 +147,8 @@ 'thread/thread_win.cc', 'win/address_types.h', 'win/checked_win_address_range.h', + 'win/module_version.cc', + 'win/module_version.h', 'win/process_info.cc', 'win/process_info.h', 'win/process_structs.h', diff --git a/util/win/module_version.cc b/util/win/module_version.cc new file mode 100644 index 00000000..a887b2c7 --- /dev/null +++ b/util/win/module_version.cc @@ -0,0 +1,55 @@ +// Copyright 2015 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "util/win/module_version.h" + +#include + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/strings/utf_string_conversions.h" + +namespace crashpad { + +bool GetModuleVersionAndType(const base::FilePath& path, + VS_FIXEDFILEINFO* vs_fixedfileinfo) { + DWORD size = GetFileVersionInfoSize(path.value().c_str(), nullptr); + if (!size) { + PLOG(WARNING) << "GetFileVersionInfoSize: " + << base::UTF16ToUTF8(path.value()); + } else { + scoped_ptr data(new uint8_t[size]); + if (!GetFileVersionInfo(path.value().c_str(), 0, size, data.get())) { + PLOG(WARNING) << "GetFileVersionInfo: " + << base::UTF16ToUTF8(path.value()); + } else { + VS_FIXEDFILEINFO* fixed_file_info; + UINT size; + if (!VerQueryValue(data.get(), + L"\\", + reinterpret_cast(&fixed_file_info), + &size)) { + PLOG(WARNING) << "VerQueryValue"; + } else { + *vs_fixedfileinfo = *fixed_file_info; + vs_fixedfileinfo->dwFileFlags &= vs_fixedfileinfo->dwFileFlagsMask; + return true; + } + } + } + + return false; +} + +} // namespace crashpad diff --git a/util/win/module_version.h b/util/win/module_version.h new file mode 100644 index 00000000..e7d37692 --- /dev/null +++ b/util/win/module_version.h @@ -0,0 +1,37 @@ +// Copyright 2015 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_UTIL_WIN_MODULE_VERSION_H_ +#define CRASHPAD_UTIL_WIN_MODULE_VERSION_H_ + +#include + +#include "base/files/file_path.h" + +namespace crashpad { + +//! \brief Retrieve the type and version information from a given module (exe, +//! dll, etc.) +//! +//! \param[in] path The path to the module to be inspected. +//! \param[out] vs_fixedfileinfo The VS_FIXEDFILEINFO on success. `dwFileFlags` +//! will have been masked with `dwFileFlagsMask` already. +//! +//! \return `true` on success, or `false` on failure with a message logged. +bool GetModuleVersionAndType(const base::FilePath& path, + VS_FIXEDFILEINFO* vs_fixedfileinfo); + +} // namespace crashpad + +#endif // CRASHPAD_UTIL_WIN_MODULE_VERSION_H_ diff --git a/util/win/process_structs.h b/util/win/process_structs.h index 6cd06b0f..65f0aac0 100644 --- a/util/win/process_structs.h +++ b/util/win/process_structs.h @@ -312,7 +312,7 @@ struct TEB { }; // See https://msdn.microsoft.com/en-us/library/gg750724.aspx for the base -// structure, and +// structure, and // http://processhacker.sourceforge.net/doc/struct___s_y_s_t_e_m___e_x_t_e_n_d_e_d___t_h_r_e_a_d___i_n_f_o_r_m_a_t_i_o_n.html // for the extension part. template