removable drive manager - Windows part

This commit is contained in:
David Kocik 2019-11-26 14:19:29 +01:00
parent 62e36cd2d5
commit 8b4732e811
3 changed files with 195 additions and 0 deletions

View file

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

View file

@ -0,0 +1,149 @@
#include "RemovableDriveManager.hpp"
#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));
}
}
}
}
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);
}
}
}}

View file

@ -0,0 +1,41 @@
#ifndef slic3r_GUI_RemovableDriveManager_hpp_
#define slic3r_GUI_RemovableDriveManager_hpp_
#include <vector>
#include <string>
namespace Slic3r {
namespace GUI {
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()
{
static RemovableDriveManager instance;
return instance;
}
RemovableDriveManager(RemovableDriveManager const&) = delete;
void operator=(RemovableDriveManager const&) = delete;
//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