first commit
This commit is contained in:
340
project/fm_viewer/core/rm_usb.cpp
Normal file
340
project/fm_viewer/core/rm_usb.cpp
Normal file
@@ -0,0 +1,340 @@
|
||||
#include "rm_usb.h"
|
||||
#include <Windows.h>
|
||||
#include <dbt.h>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
#if (RM_MODEL_EMT_KR)
|
||||
#include "../cfg/rm_settings_cfg_emt_kr.h"
|
||||
#endif
|
||||
|
||||
#if (DETECT_SETTING_USB_EJECT || DETECT_USB_CHANGE)
|
||||
|
||||
rm_usb::rm_usb(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
_hDevNotify = NULL;
|
||||
_insertringDrive = 0;
|
||||
_removingDrive = 0;
|
||||
_openDrive = "";
|
||||
_irTimer = NULL;
|
||||
}
|
||||
rm_usb::~rm_usb()
|
||||
{
|
||||
if(_hDevNotify != NULL) {
|
||||
::UnregisterDeviceNotification(_hDevNotify);
|
||||
}
|
||||
_cancelIRTimer();
|
||||
}
|
||||
|
||||
// 항상 대문자로 리턴됨
|
||||
char rm_usb::_firstDriveFromMask( uint unitmask )
|
||||
{
|
||||
char i;
|
||||
|
||||
for (i = 0; i < 26; ++i)
|
||||
{
|
||||
if (unitmask & 0x1)
|
||||
break;
|
||||
unitmask = unitmask >> 1;
|
||||
}
|
||||
return( i + 'A' );
|
||||
}
|
||||
void rm_usb::_startIRTimer()
|
||||
{
|
||||
_cancelIRTimer();
|
||||
_irTimer = new QTimer(this);
|
||||
_irTimer->setSingleShot(true);
|
||||
_irTimer->setInterval(1000);
|
||||
connect(_irTimer,SIGNAL(timeout()),SLOT(onClearIR()));
|
||||
_irTimer->start();
|
||||
}
|
||||
void rm_usb::_cancelIRTimer()
|
||||
{
|
||||
if(_irTimer != NULL) {
|
||||
_irTimer->stop();
|
||||
delete _irTimer;
|
||||
_irTimer = NULL;
|
||||
}
|
||||
}
|
||||
void rm_usb::onClearIR()
|
||||
{
|
||||
_insertringDrive = 0;
|
||||
_removingDrive = 0;
|
||||
}
|
||||
|
||||
bool rm_usb::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
Q_UNUSED(result);
|
||||
#ifdef Q_OS_WIN32
|
||||
MSG *msg = (MSG *)message;
|
||||
if( WM_DEVICECHANGE == msg->message && DBT_DEVICEARRIVAL == msg->wParam )
|
||||
{
|
||||
DEV_BROADCAST_HDR* dev = (DEV_BROADCAST_HDR*)msg->lParam;
|
||||
if (dev->dbch_devicetype == DBT_DEVTYP_VOLUME)
|
||||
{
|
||||
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)dev;
|
||||
char driver = _firstDriveFromMask(lpdbv->dbcv_unitmask);
|
||||
|
||||
// 다중 호출 방지 -> 처리 끝나면 초기화 해야 함
|
||||
if (_insertringDrive != driver)
|
||||
{
|
||||
_insertringDrive = driver;
|
||||
QString driver_letter(driver);
|
||||
driver_letter += ":";
|
||||
// qInfo() << "USB arrival detected:" << driver;
|
||||
*result = 1;
|
||||
emit usbChanged(true,driver_letter);
|
||||
_startIRTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( WM_DEVICECHANGE == msg->message && DBT_DEVICEREMOVECOMPLETE == msg->wParam )
|
||||
{
|
||||
DEV_BROADCAST_HDR* dev = (DEV_BROADCAST_HDR*)msg->lParam;
|
||||
if (dev->dbch_devicetype == DBT_DEVTYP_VOLUME)
|
||||
{
|
||||
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)dev;
|
||||
char driver = _firstDriveFromMask(lpdbv->dbcv_unitmask);
|
||||
if (_removingDrive != driver)
|
||||
{
|
||||
_removingDrive = driver;
|
||||
QString driver_letter(driver);
|
||||
driver_letter += ":";
|
||||
// qInfo() << "USB departure detected:" << " driver:" << driver;
|
||||
*result = 1;
|
||||
emit usbChanged(false,driver_letter);
|
||||
_startIRTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // Q_OS_WIN32
|
||||
// Return false so that the event is propagated
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void rm_usb::registerEvent(QWidget *window)
|
||||
{
|
||||
if( window != nullptr )
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
|
||||
//GUID WusbrawGUID = {0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed };
|
||||
//GUID WusbGUID = {0x88BAE032, 0x5A81, 0x49f0, 0xBC, 0x3D, 0xA4, 0xFF, 0x13, 0x82, 0x16, 0xD6 };
|
||||
|
||||
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
|
||||
|
||||
::ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
|
||||
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
||||
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
NotificationFilter.dbcc_classguid = WceusbshGUID;
|
||||
_hDevNotify = ::RegisterDeviceNotification((HANDLE)window->winId(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
if( NULL == _hDevNotify )
|
||||
{
|
||||
// Print error
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
bool rm_usb::isRemovablePath(QString path)
|
||||
{
|
||||
if(path.contains(":")) {
|
||||
QString driver = path.split(":").first();
|
||||
WCHAR diskName[4] = {0,};
|
||||
driver = driver.left(1) + ":\\";
|
||||
driver.toWCharArray(diskName);
|
||||
if(::GetDriveType(diskName) == DRIVE_REMOVABLE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void rm_usb::setOpenDriveWithPath(QString path)
|
||||
{
|
||||
if(rm_usb::isRemovablePath(path)) {
|
||||
_openDrive = path.left(1).toUpper() + ":";
|
||||
}
|
||||
}
|
||||
int rm_usb::isDeviceDriver(QString folder, bool loadCFG)
|
||||
{
|
||||
#if (RM_MODEL_TB) // RM_MODEL == RM_MODEL_TYPE_TB4000
|
||||
return QDir(folder).exists() && QDir(folder + QDir::separator() + QString("Video")).exists() && QDir(folder + QDir::separator() + QString("Photo")).exists();
|
||||
#elif (RM_MODEL_EMT_KR)
|
||||
// 각 모델별로 확인
|
||||
for(int i=0;i<CFG::model_names.size();i++) {
|
||||
QString path = folder + "Setting" + QDir::separator() + CFG::model_names.at(i) + "_setting.cfg";
|
||||
if(QFile::exists(path)) {
|
||||
// 설정파일 읽을 필요 없음
|
||||
if(!loadCFG) {
|
||||
return 0;
|
||||
}
|
||||
// checksum + 크기 + 모델코드 확인
|
||||
CFG_ERROR_CODE code = CFG::load(path);
|
||||
if(code != CFG_SUCCESS) {
|
||||
if(code == CFG_CHECKSUM_ERROR) {
|
||||
return code;
|
||||
}
|
||||
//qInfo() << path << " MODEL CODE:" << CFG::info.model << "ERROR:" << code << __FUNCTION__;
|
||||
}
|
||||
if(code == CFG_SUCCESS && CFG::info.model == CFG::model_codes[i])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// E:\Setting , NM5000_setting.cfg
|
||||
// Magnus : 5101
|
||||
// Trinity : 5102
|
||||
// Mirror5 : 5103
|
||||
// Pro5 : 5104
|
||||
// 360X : 5105
|
||||
|
||||
return 999;
|
||||
#else //
|
||||
return false;
|
||||
#endif;
|
||||
}
|
||||
|
||||
// Disk 의 볼륨명이 모델명과 동일함
|
||||
#if (RM_MODEL_EMT_KR)
|
||||
QString rm_usb::getRemovableDisk()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
WCHAR szLogicalDrives[MAX_PATH * sizeof(TCHAR)];
|
||||
DWORD dwByte = ::GetLogicalDriveStrings(MAX_PATH, szLogicalDrives);
|
||||
|
||||
for(DWORD i=0; i<dwByte / 4; i++)
|
||||
{
|
||||
WCHAR* diskName = &szLogicalDrives[i * 4];
|
||||
UINT type = ::GetDriveType(diskName);
|
||||
if(DRIVE_REMOVABLE == type)
|
||||
{
|
||||
#if (!NO_SD_CHECK)
|
||||
QString diskLetter = QString::fromUtf16((const ushort*)diskName);
|
||||
|
||||
diskLetter.replace("\\","");
|
||||
|
||||
diskLetter = "\\\\.\\" + diskLetter;
|
||||
|
||||
// qInfo() << "check disk name:" << diskLetter;
|
||||
// empty media check
|
||||
HANDLE hDisk = ::CreateFile(reinterpret_cast<LPCWSTR>(diskLetter.utf16()),
|
||||
FILE_READ_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if(hDisk == INVALID_HANDLE_VALUE || hDisk == NULL)
|
||||
{
|
||||
//qInfo() << "INVALID_HANDLE_VALUE" << diskLetter << "type" << type;
|
||||
continue;
|
||||
}
|
||||
|
||||
DWORD dwBytesReturned;
|
||||
ULONG MediaChangeCount;
|
||||
BOOL res = ::DeviceIoControl( hDisk,
|
||||
IOCTL_STORAGE_CHECK_VERIFY,
|
||||
NULL,
|
||||
0,
|
||||
&MediaChangeCount,
|
||||
sizeof(ULONG),
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
::CloseHandle(hDisk);
|
||||
if(res == FALSE)
|
||||
{
|
||||
//qInfo() << "empty" << QString::fromUtf16((const ushort*)diskName) << "type" << type;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
QString diskPath = QString::fromUtf16((const ushort*)diskName);
|
||||
// 설정파일 존재 확인
|
||||
if(isDeviceDriver(diskPath,false) == 0) {
|
||||
return diskPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
#else // TB
|
||||
QString rm_usb::getRemovableDisk(QString volume)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
WCHAR szLogicalDrives[MAX_PATH * sizeof(TCHAR)];
|
||||
DWORD dwByte = ::GetLogicalDriveStrings(MAX_PATH, szLogicalDrives);
|
||||
|
||||
for(DWORD i=0; i<dwByte / 4; i++)
|
||||
{
|
||||
WCHAR* diskName = &szLogicalDrives[i * 4];
|
||||
UINT type = ::GetDriveType(diskName);
|
||||
if(DRIVE_REMOVABLE == type)
|
||||
{
|
||||
|
||||
#if (!NO_SD_CHECK)
|
||||
QString diskLetter = QString::fromUtf16((const ushort*)diskName);
|
||||
|
||||
diskLetter.replace("\\","");
|
||||
|
||||
diskLetter = "\\\\.\\" + diskLetter;
|
||||
|
||||
// qInfo() << "check disk name:" << diskLetter;
|
||||
// empty media check
|
||||
HANDLE hDisk = ::CreateFile(reinterpret_cast<LPCWSTR>(diskLetter.utf16()),
|
||||
FILE_READ_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if(hDisk == INVALID_HANDLE_VALUE || hDisk == NULL)
|
||||
{
|
||||
//qInfo() << "INVALID_HANDLE_VALUE" << diskLetter << "type" << type;
|
||||
continue;
|
||||
}
|
||||
|
||||
DWORD dwBytesReturned;
|
||||
ULONG MediaChangeCount;
|
||||
BOOL res = ::DeviceIoControl( hDisk,
|
||||
IOCTL_STORAGE_CHECK_VERIFY,
|
||||
NULL,
|
||||
0,
|
||||
&MediaChangeCount,
|
||||
sizeof(ULONG),
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
::CloseHandle(hDisk);
|
||||
if(res == FALSE)
|
||||
{
|
||||
//qInfo() << "empty" << QString::fromUtf16((const ushort*)diskName) << "type" << type;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
WCHAR volumeNameW[MAX_PATH * sizeof(TCHAR)] = {0,};
|
||||
|
||||
::GetVolumeInformation(diskName,volumeNameW, 1024, NULL, NULL, NULL, NULL, MAX_PATH);
|
||||
|
||||
QString volumeName = QString::fromUtf16((const ushort*)volumeNameW);
|
||||
QString diskPath = QString::fromUtf16((const ushort*)diskName);
|
||||
//qInfo() << volumeName << __FUNCTION__;
|
||||
if(volume.isEmpty() || volume.compare(volumeName,Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
diskPath = diskPath.replace("\\","");
|
||||
//rm_usb::current_driver = diskPath.at(0).toLatin1();
|
||||
return diskPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
#endif // #if (RM_MODEL_EMT_KR)
|
||||
#endif // #if (USE_SD_CARD_DETECT)
|
||||
Reference in New Issue
Block a user