mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-25 13:25:37 +00:00
Windows: Show volume names beside drives letters in tooltips.
This commit is contained in:
@@ -88,13 +88,20 @@ The drives may be duplicated as pdX (with X and N being unrelated).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct DriveLetterInfo {
|
||||
std::set<int> physical_drives; ///< N in pdN
|
||||
std::string volume_name; ///< Volume name
|
||||
};
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
/// Check which physical drives each drive letter (C, D, ...) spans across.
|
||||
std::map<char, std::set<int> > win32_get_drive_letter_map()
|
||||
std::map<char, DriveLetterInfo> win32_get_drive_letter_map()
|
||||
{
|
||||
std::map<char, std::set<int> > drive_letter_map;
|
||||
std::map<char, DriveLetterInfo> drive_letter_map;
|
||||
|
||||
std::bitset<32> drives(GetLogicalDrives());
|
||||
|
||||
@@ -130,12 +137,27 @@ std::map<char, std::set<int> > win32_get_drive_letter_map()
|
||||
continue;
|
||||
}
|
||||
|
||||
std::set<int> drive_numbers;
|
||||
std::set<int> physical_drives;
|
||||
for (int i = 0; i < vde.NumberOfDiskExtents; ++i) {
|
||||
drive_numbers.insert(vde.Extents[i].DiskNumber);
|
||||
physical_drives.insert(vde.Extents[i].DiskNumber);
|
||||
debug_out_dump("app", "Windows drive " << drive << " corresponds to physical drive " << vde.Extents[i].DiskNumber << ".\n");
|
||||
}
|
||||
drive_letter_map[drive] = drive_numbers;
|
||||
|
||||
std::string volume_name;
|
||||
wchar_t volume_name_w[MAX_PATH+1] = {0};
|
||||
DWORD dummy = 0;
|
||||
hz::scoped_array<wchar_t> drive_name(hz::win32_utf8_to_utf16((drive + std::string(":\\")).c_str()));
|
||||
if (drive_name && GetVolumeInformationW(drive_name.get(),
|
||||
volume_name_w, MAX_PATH+1,
|
||||
NULL, &dummy, &dummy, NULL, 0)) {
|
||||
volume_name = hz::win32_utf16_to_utf8_string(volume_name_w);
|
||||
}
|
||||
|
||||
DriveLetterInfo dli;
|
||||
dli.physical_drives = physical_drives;
|
||||
dli.volume_name = volume_name;
|
||||
|
||||
drive_letter_map[drive] = dli;
|
||||
}
|
||||
|
||||
return drive_letter_map;
|
||||
@@ -148,7 +170,7 @@ std::map<char, std::set<int> > win32_get_drive_letter_map()
|
||||
/// conflict with pd* devices, and we like pd* better than sd*.
|
||||
std::string get_scan_open_multiport_devices(std::vector<StorageDeviceRefPtr>& drives,
|
||||
ExecutorFactoryRefPtr ex_factory,
|
||||
const std::map<char, std::set<int> >& drive_letter_map,
|
||||
const std::map<char, DriveLetterInfo>& drive_letter_map,
|
||||
std::set<int>& equivalent_pds)
|
||||
{
|
||||
debug_out_info("app", "Getting multi-port devices through smartctl --scan-open...\n");
|
||||
@@ -215,13 +237,13 @@ std::string get_scan_open_multiport_devices(std::vector<StorageDeviceRefPtr>& dr
|
||||
std::string full_dev = dev + "," + port_str;
|
||||
StorageDeviceRefPtr drive(new StorageDevice(full_dev, type));
|
||||
|
||||
std::vector<char> drive_letters;
|
||||
for (std::map<char, std::set<int> >::const_iterator iter = drive_letter_map.begin(); iter != drive_letter_map.end(); ++iter) {
|
||||
if (iter->second.count(drive_num) > 0) {
|
||||
drive_letters.push_back(iter->first);
|
||||
std::map<char, std::string> letters_volnames;
|
||||
for (std::map<char, DriveLetterInfo>::const_iterator iter = drive_letter_map.begin(); iter != drive_letter_map.end(); ++iter) {
|
||||
if (iter->second.physical_drives.count(drive_num) > 0) {
|
||||
letters_volnames[iter->first] = iter->second.volume_name;
|
||||
}
|
||||
}
|
||||
drive->set_drive_letters(drive_letters);
|
||||
drive->set_drive_letters(letters_volnames);
|
||||
|
||||
drives.push_back(drive);
|
||||
}
|
||||
@@ -632,7 +654,7 @@ std::string detect_drives_win32(std::vector<StorageDeviceRefPtr>& drives, Execut
|
||||
|
||||
// Construct drive letter map
|
||||
debug_out_info("app", "Checking which drive corresponds to which \\\\.\\PhysicalDriveN device...\n");
|
||||
std::map<char, std::set<int> > drive_letter_map = win32_get_drive_letter_map();
|
||||
std::map<char, DriveLetterInfo> drive_letter_map = win32_get_drive_letter_map();
|
||||
|
||||
|
||||
hz::intrusive_ptr<CmdexSync> smartctl_ex = ex_factory->create_executor(ExecutorFactory::ExecutorSmartctl);
|
||||
@@ -711,14 +733,14 @@ std::string detect_drives_win32(std::vector<StorageDeviceRefPtr>& drives, Execut
|
||||
|
||||
StorageDeviceRefPtr drive(new StorageDevice(hz::string_sprintf("pd%d", drive_num)));
|
||||
|
||||
std::vector<char> letters;
|
||||
for (std::map<char, std::set<int> >::iterator iter = drive_letter_map.begin(); iter != drive_letter_map.end(); ++iter) {
|
||||
if (iter->second.count(drive_num) > 0) {
|
||||
letters.push_back(iter->first);
|
||||
std::map<char, std::string> letters_volnames;
|
||||
for (std::map<char, DriveLetterInfo>::const_iterator iter = drive_letter_map.begin(); iter != drive_letter_map.end(); ++iter) {
|
||||
if (iter->second.physical_drives.count(drive_num) > 0) {
|
||||
letters_volnames[iter->first] = iter->second.volume_name;
|
||||
}
|
||||
}
|
||||
drive->set_drive_letters(letters);
|
||||
debug_out_dump("app", "Drive letters for: " << drive->get_device() << ": " << drive->format_drive_letters() << ".\n");
|
||||
drive->set_drive_letters(letters_volnames);
|
||||
debug_out_dump("app", "Drive letters for: " << drive->get_device() << ": " << drive->format_drive_letters(true) << ".\n");
|
||||
|
||||
// Sometimes, a single physical drive may be accessible from both "/.//PhysicalDriveN"
|
||||
// and "/.//Scsi2" (e.g. pd0 and csmi2,1). Prefer the port-having ones (which is from --scan-open),
|
||||
|
||||
@@ -651,25 +651,28 @@ std::string StorageDevice::get_extra_arguments() const
|
||||
|
||||
|
||||
|
||||
void StorageDevice::set_drive_letters(const std::vector< char >& letters)
|
||||
void StorageDevice::set_drive_letters(const std::map<char, std::string>& letters)
|
||||
{
|
||||
drive_letters_ = letters;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::vector< char >& StorageDevice::get_drive_letters() const
|
||||
const std::map<char, std::string>& StorageDevice::get_drive_letters() const
|
||||
{
|
||||
return drive_letters_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string StorageDevice::format_drive_letters() const
|
||||
std::string StorageDevice::format_drive_letters(bool with_volnames) const
|
||||
{
|
||||
std::vector<std::string> drive_letters_decorated;
|
||||
for (std::size_t i = 0; i < drive_letters_.size(); ++i) {
|
||||
drive_letters_decorated.push_back(std::string() + (char)std::toupper(drive_letters_[i]) + ":");
|
||||
for (std::map<char, std::string>::const_iterator iter = drive_letters_.cbegin(); iter != drive_letters_.cend(); ++iter) {
|
||||
drive_letters_decorated.push_back(std::string() + (char)std::toupper(iter->first) + ":");
|
||||
if (with_volnames && !iter->second.empty()) {
|
||||
drive_letters_decorated.back() += std::string(" (") + iter->second + ")";
|
||||
}
|
||||
}
|
||||
return hz::string_join(drive_letters_decorated, ", ");
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define STORAGE_DEVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <sigc++/sigc++.h>
|
||||
|
||||
#include "hz/optional_value.h"
|
||||
@@ -166,13 +167,13 @@ class StorageDevice : public hz::intrusive_ptr_referenced {
|
||||
|
||||
|
||||
/// Set windows drive letters for this drive
|
||||
void set_drive_letters(const std::vector<char>& letters);
|
||||
void set_drive_letters(const std::map<char, std::string>& letters_volnames);
|
||||
|
||||
/// Get windows drive letters for this drive
|
||||
const std::vector<char>& get_drive_letters() const;
|
||||
const std::map<char, std::string>& get_drive_letters() const;
|
||||
|
||||
/// Get comma-separated win32 drive letters (if present)
|
||||
std::string format_drive_letters() const;
|
||||
std::string format_drive_letters(bool with_volnames) const;
|
||||
|
||||
|
||||
/// Get "virtual" status
|
||||
@@ -275,7 +276,7 @@ class StorageDevice : public hz::intrusive_ptr_referenced {
|
||||
std::string type_arg_; ///< Device type (for -d smartctl parameter), as specified when adding the device.
|
||||
std::string extra_args_; ///< Extra parameters for smartctl, as specified when adding the device.
|
||||
|
||||
std::vector<char> drive_letters_; ///< Windows drive letters (if detected)
|
||||
std::map<char, std::string> drive_letters_; ///< Windows drive letters (if detected), with volume names
|
||||
|
||||
bool is_virtual_; ///< If true, then this is not a real device - merely a loaded description of it.
|
||||
std::string virtual_file_; ///< A file (smartctl data) the virtual device was loaded from
|
||||
|
||||
@@ -464,7 +464,7 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
{
|
||||
std::string device = Glib::Markup::escape_text(drive->get_device_with_type());
|
||||
std::string model = Glib::Markup::escape_text(drive->get_model_name().empty() ? "Unknown model" : drive->get_model_name());
|
||||
std::string drive_letters = Glib::Markup::escape_text(drive->format_drive_letters());
|
||||
std::string drive_letters = Glib::Markup::escape_text(drive->format_drive_letters(false));
|
||||
|
||||
this->set_title("Device Information - " + device + ": " + model + " - GSmartControl");
|
||||
|
||||
|
||||
@@ -946,7 +946,7 @@ void GscMainWindow::update_status_widgets()
|
||||
std::string model = Glib::Markup::escape_text(drive->get_model_name().empty() ? std::string("Unknown model") : drive->get_model_name());
|
||||
std::string family = Glib::Markup::escape_text(drive->get_family_name().empty() ? "Unknown" : drive->get_family_name());
|
||||
std::string family_fallback = Glib::Markup::escape_text(drive->get_family_name().empty() ? model : drive->get_family_name());
|
||||
std::string drive_letters_str = Glib::Markup::escape_text(drive->format_drive_letters());
|
||||
std::string drive_letters_str = Glib::Markup::escape_text(drive->format_drive_letters(false));
|
||||
|
||||
std::string info_str = device
|
||||
+ (drive_letters_str.empty() ? "" : (" (<b>" + drive_letters_str + "</b>)"))
|
||||
|
||||
@@ -282,10 +282,14 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
|
||||
// it needs this space to be symmetric (why?);
|
||||
std::string name; // = "<big>" + drive->get_device_with_type() + " </big>\n";
|
||||
Glib::ustring drive_letters = Glib::Markup::escape_text(drive->format_drive_letters());
|
||||
Glib::ustring drive_letters = Glib::Markup::escape_text(drive->format_drive_letters(false));
|
||||
if (drive_letters.empty()) {
|
||||
drive_letters = "not mounted";
|
||||
}
|
||||
Glib::ustring drive_letters_with_volname = Glib::Markup::escape_text(drive->format_drive_letters(true));
|
||||
if (drive_letters_with_volname.empty()) {
|
||||
drive_letters_with_volname = "not mounted";
|
||||
}
|
||||
|
||||
// note: if this wraps, it becomes left-aligned in gtk <= 2.10.
|
||||
name += (drive->get_model_name().empty() ? Glib::ustring("Unknown model") : Glib::Markup::escape_text(drive->get_model_name()));
|
||||
@@ -323,7 +327,7 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
tooltip_strs.push_back("Drive letters: <b>" + drive_letters + "</b>");
|
||||
tooltip_strs.push_back("Drive letters: <b>" + drive_letters_with_volname + "</b>");
|
||||
#endif
|
||||
|
||||
if (!drive->get_serial_number().empty()) {
|
||||
|
||||
Reference in New Issue
Block a user