From 0836df93e1f1692544fcdc8a89677f321c57f66a Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 9 Mar 2020 14:25:02 +0100 Subject: [PATCH 1/2] enumarating removable drives on mac - added Secure Digital option hopefully a fix for issue #3793 --- src/slic3r/GUI/RemovableDriveManager.cpp | 6 +++-- src/slic3r/GUI/RemovableDriveManagerMM.mm | 29 +++++++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 0c4c417b2..1580c5025 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -338,9 +338,11 @@ void RemovableDriveManager::eject_drive() // there is no usable command in c++ so terminal command is used instead // but neither triggers "succesful safe removal messege" std::string command = -#if __APPLE__ - //this->eject_device(m_last_save_path); +#if __APPLE__ "diskutil unmount "; + //Another option how to eject at mac. Currently not working. + //used insted of system() command; + //this->eject_device(correct_path); #else "umount "; #endif diff --git a/src/slic3r/GUI/RemovableDriveManagerMM.mm b/src/slic3r/GUI/RemovableDriveManagerMM.mm index c2f55bb79..3e4b32f29 100644 --- a/src/slic3r/GUI/RemovableDriveManagerMM.mm +++ b/src/slic3r/GUI/RemovableDriveManagerMM.mm @@ -4,10 +4,22 @@ #import #import +static void eject_callback(DADiskRef disk, DADissenterRef dissenter, void *context) +{ + NSLog(@"eject successfull"); +} + +static void unmount_callback(DADiskRef disk, DADissenterRef dissenter, void *context) +{ + //if (dissenter) { + //? + //} else { + DADiskEject(disk, kDADiskEjectOptionDefault, eject_callback, context); + //} +} + @implementation RemovableDriveManagerMM - - -(instancetype) init { self = [super init]; @@ -59,9 +71,17 @@ CFTypeRef mediaEjectableKey = CFDictionaryGetValue(descDict,kDADiskDescriptionMediaEjectableKey); BOOL ejectable = [mediaEjectableKey boolValue]; CFTypeRef deviceProtocolName = CFDictionaryGetValue(descDict,kDADiskDescriptionDeviceProtocolKey); + CFTypeRef deviceModelKey = CFDictionaryGetValue(descDict, kDADiskDescriptionDeviceModelKey); + //debug logging + /* + if (deviceProtocolName) + NSLog(@"%@",(CFStringRef)deviceProtocolName); + if (deviceModelKey) + NSLog(@"-%@",(CFStringRef)deviceModelKey); + */ if (mediaEjectableKey != nullptr) { - BOOL op = ejectable && (CFEqual(deviceProtocolName, CFSTR("USB")) || CFEqual(deviceModelKey, CFSTR("SD Card Reader"))); + BOOL op = ejectable && (CFEqual(deviceProtocolName, CFSTR("USB")) || CFEqual(deviceModelKey, CFSTR("SD Card Reader")) || CFEqual(deviceProtocolName, CFSTR("Secure Digital"))); //!CFEqual(deviceModelKey, CFSTR("Disk Image")); if (op) [result addObject:volURL.path]; @@ -86,7 +106,8 @@ if (err == 0) disk = DADiskCreateFromVolumePath(nullptr,session,(CFURLRef)url); if( err == 0) - DADiskUnmount(disk, kDADiskUnmountOptionDefault, nullptr, nullptr); + //DADiskUnmount(disk, kDADiskUnmountOptionDefault, nullptr, nullptr); + DADiskUnmount(disk, kDADiskUnmountOptionWhole | kDADiskUnmountOptionForce, unmount_callback, nullptr); if (disk != nullptr) CFRelease(disk); if (session != nullptr) From e6035542fa032b95d5b8532f1577b4a130f6ea92 Mon Sep 17 00:00:00 2001 From: David Kocik Date: Tue, 10 Mar 2020 08:28:27 +0100 Subject: [PATCH 2/2] ejecting sd card/flash drives with boost::process::child on mac/linux --- src/slic3r/GUI/RemovableDriveManager.cpp | 30 +++++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 1580c5025..f76625049 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #endif namespace Slic3r { @@ -329,29 +330,40 @@ void RemovableDriveManager::eject_drive() auto it_drive_data = this->find_last_save_path_drive_data(); if (it_drive_data != m_current_drives.end()) { std::string correct_path(m_last_save_path); - for (size_t i = 0; i < correct_path.size(); ++i) +#ifndef __APPLE__ + for (size_t i = 0; i < correct_path.size(); ++i) if (correct_path[i]==' ') { correct_path = correct_path.insert(i,1,'\\'); ++ i; } +#endif //std::cout<<"Ejecting "<<(*it).name<<" from "<< correct_path<<"\n"; // there is no usable command in c++ so terminal command is used instead // but neither triggers "succesful safe removal messege" - std::string command = + BOOST_LOG_TRIVIAL(info) << "Ejecting started"; + boost::process::ipstream istd_err; + boost::process::child child( #if __APPLE__ - "diskutil unmount "; + boost::process::search_path("diskutil"), "eject", correct_path.c_str(), (boost::process::std_out & boost::process::std_err) > istd_err); //Another option how to eject at mac. Currently not working. //used insted of system() command; //this->eject_device(correct_path); #else - "umount "; + boost::process::search_path("umount"), correct_path.c_str(), (boost::process::std_out & boost::process::std_err) > istd_err); #endif - command += correct_path; - int err = system(command.c_str()); - if (err) { - BOOST_LOG_TRIVIAL(error) << "Ejecting " << m_last_save_path << " failed"; - return; + std::string line; + while (child.running() && std::getline(istd_err, line)) { + BOOST_LOG_TRIVIAL(trace) << line; } + // wait for command to finnish (blocks ui thread) + child.wait(); + int err = child.exit_code(); + if(err) + { + BOOST_LOG_TRIVIAL(error) << "Ejecting failed"; + return; + } + BOOST_LOG_TRIVIAL(info) << "Ejecting finished"; assert(m_callback_evt_handler); if (m_callback_evt_handler)