first commit

This commit is contained in:
2026-02-21 17:11:31 +09:00
commit 18b4338361
4001 changed files with 365464 additions and 0 deletions

View 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)