removable drive manager - Windows part

This commit is contained in:
David Kocik 2019-11-26 14:19:29 +01:00
parent acab61fa54
commit f3ecf55d38
3 changed files with 191 additions and 0 deletions

View file

@ -21,6 +21,7 @@
#include <wx/string.h>
#include "I18N.hpp"
#include "RemovableDriveManager.hpp"
namespace Slic3r {
@ -357,7 +358,14 @@ void AppConfig::update_skein_dir(const std::string &dir)
std::string AppConfig::get_last_output_dir(const std::string &alt) const
{
<<<<<<< HEAD
=======
if (GUI::RemovableDriveManager::getInstance().update())
{
return GUI::RemovableDriveManager::getInstance().getLastDrivePath();
}
>>>>>>> removable drive manager - Windows part
const auto it = m_storage.find("");
if (it != m_storage.end()) {
const auto it2 = it->second.find("last_output_path");

View file

@ -1,4 +1,5 @@
#include "RemovableDriveManager.hpp"
<<<<<<< HEAD
#include <iostream>
#include "boost/nowide/convert.hpp"
@ -66,10 +67,72 @@ void RemovableDriveManager::search_for_drives()
{
path += "\\";
m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path));
=======
#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <stdio.h>
//#include <boost/log/trivial.hpp>
//#include "libslic3r/Utils.hpp"
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
namespace Slic3r {
namespace GUI {
std::vector<DriveData> RemovableDriveManager::currentDrives;
bool RemovableDriveManager::update()
{
searchForDrives(currentDrives);
return !currentDrives.empty();
}
void RemovableDriveManager::searchForDrives(std::vector<DriveData>& newDrives)
{
newDrives.clear();
newDrives.reserve(26);
DWORD drivesMask = GetLogicalDrives();
for (size_t i = 0; i < 26; i++)
{
if(drivesMask & (1 << i))
{
std::string path (1,(char)('A' + i));
path+=":";
UINT driveType = GetDriveTypeA(path.c_str());
//std::cout << "found drive" << (char)('A' + i) << ": type:" <<driveType << "\n";
if (driveType == DRIVE_REMOVABLE)
{
// get name of drive
std::wstring wpath = std::wstring(path.begin(), path.end());
std::wstring volumeName;
volumeName.resize(1024);
std::wstring fileSystemName;
fileSystemName.resize(1024);
LPWSTR lpVolumeNameBuffer = new wchar_t;
BOOL error = GetVolumeInformationW(wpath.c_str(), &volumeName[0], sizeof(volumeName), NULL, NULL, NULL, &fileSystemName[0], sizeof(fileSystemName));
if(error != 0)
{
if (volumeName == L"")
{
volumeName = L"REMOVABLE DRIVE";
}
if (fileSystemName != L"")
{
ULARGE_INTEGER freeSpace;
GetDiskFreeSpaceExA(path.c_str(), &freeSpace, NULL, NULL);
//std::cout << std::string(volumeName.begin(), volumeName.end()) << " " << std::string(fileSystemName.begin(), fileSystemName.end()) << " " << freeSpace.QuadPart << "\n";
if (freeSpace.QuadPart > 0)
{
newDrives.push_back(DriveData(volumeName, path));
>>>>>>> removable drive manager - Windows part
}
}
}
}
<<<<<<< HEAD
}
}
}
@ -518,3 +581,90 @@ void RemovableDriveManager::reset_last_save_path()
m_last_save_path = "";
}
}}//namespace Slicer::Gui
=======
else if(driveType == 3)//disks and usb drives
{
}
}
}
}
void RemovableDriveManager::updateCurrentDrives(const std::vector<DriveData>& newDrives)
{
currentDrives.clear();
currentDrives.reserve(26);
for (auto it = newDrives.begin(); it != newDrives.end(); ++it)
{
currentDrives.push_back(*it);
}
}
void RemovableDriveManager::printDrivesToLog()
{
//std::cout<<"current drives:"<< currentDrives.size() <<"\n";
for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it)
{
//BOOST_LOG_TRIVIAL(trace) << boost::format("found disk %1%:") % ('A' + i);
//std::cout << /*std::string((*it).name.begin(), (*it).name.end()) << "(" << */(*it).path << ":/, ";
}
//std::cout << "\n";
}
bool RemovableDriveManager::isDriveMounted(std::string path)
{
for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it)
{
if ((*it).path == path)
{
return true;
}
}
return false;
}
void RemovableDriveManager::ejectDrive(std::string path)
{
if (!update() || !isDriveMounted(path))
return;
path = "\\\\.\\"+path;
HANDLE handle = CreateFileA(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if(handle == INVALID_HANDLE_VALUE)
{
std::cerr << "Ejecting " << path << " failed " << GetLastError() << " \n";
return;
}
DWORD deviceControlRetVal(0);
BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0,nullptr , 0, &deviceControlRetVal, nullptr);
CloseHandle(handle);
if(error != 0)
std::cout << "Ejected " << path << "\n";
else
std::cerr << "Ejecting " << path << " failed "<< deviceControlRetVal << " " << GetLastError() <<" \n";
for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it)
{
if ((*it).path == path)
{
currentDrives.erase(it);
break;
}
}
}
std::string RemovableDriveManager::getLastDrivePath()
{
if (!currentDrives.empty())
{
return currentDrives.back().path;
}
return "";
}
void RemovableDriveManager::getAllDrives(std::vector<DriveData>& drives)
{
drives.clear();
drives.reserve(26);
for (auto it = currentDrives.begin(); it != currentDrives.end(); ++it)
{
drives.push_back(*it);
}
}
}}
>>>>>>> removable drive manager - Windows part

View file

@ -6,6 +6,7 @@
namespace Slic3r {
namespace GUI {
<<<<<<< HEAD
#if __APPLE__
class RDMMMWrapper;
#endif
@ -23,12 +24,25 @@ friend class RDMMMWrapper;
#endif
public:
static RemovableDriveManager& get_instance()
=======
struct DriveData
{
std::wstring name;
std::string path;
DriveData(std::wstring n, std::string p):name(n),path(p){}
};
class RemovableDriveManager
{
public:
static RemovableDriveManager& getInstance()
>>>>>>> removable drive manager - Windows part
{
static RemovableDriveManager instance;
return instance;
}
RemovableDriveManager(RemovableDriveManager const&) = delete;
void operator=(RemovableDriveManager const&) = delete;
<<<<<<< HEAD
//call only once. on apple register for unmnount callbacks. on windows register for device notification is prepared but not called (eject usb drive on widnows doesnt trigger the callback, sdc ard does), also enumerates devices for first time so init shoud be called on linux too.
void init();
//update() searches for removable devices, returns false if empty. /time = 0 is forced update, time expects wxGetLocalTime()
@ -94,3 +108,22 @@ protected:
#endif
}}
#endif
=======
//update() searches for removable devices, returns false if empty.
static bool update();
static bool isDriveMounted(std::string path);
static void ejectDrive(std::string path);
static std::string getLastDrivePath();
static void getAllDrives(std::vector<DriveData>& drives);
private:
RemovableDriveManager(){}
static void searchForDrives(std::vector<DriveData>& newDrives);
static void printDrivesToLog();
static void updateCurrentDrives(const std::vector<DriveData>& newDrives);
static std::vector<DriveData> currentDrives;
};
}}
#endif
>>>>>>> removable drive manager - Windows part