/******************************************************************************
QDeviceWatcherPrivate: watching depends on platform
Copyright (C) 2011-2015 Wang Bin <wbsecg1@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
#include "qdevicewatcher.h"
#include "qdevicewatcher_p.h"
//TODO: If wince works, use Q_OS_WIN
#ifdef Q_OS_WIN32
#include <QtCore/QStringList>
#include <QtCore/QCoreApplication>
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#include <dbt.h>
#ifndef DBT_CUSTOMEVENT
# define DBT_CUSTOMEVENT 0x8006
#endif
#define CONFIG_NOTIFICATION 0
/*
*http://www.codeproject.com/Articles/14500/Detecting-Hardware-Insertion-and-or-Removal
*http://blog.csdn.net/sxbluebird/article/details/2445145
*/
#if CONFIG_NOTIFICATION
static HDEVNOTIFY hDevNotify = 0;
#define HID_CLASSGUID {0x4d1e55b2, 0xf16f, 0x11cf,{ 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}}
static const GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
static const GUID GUID_DEVINTERFACE_USBSTOR = { 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
static const GUID InterfaceClassGuid = GUID_DEVINTERFACE_USBSTOR;//(GUID)HID_CLASSGUID; //GUID_DEVINTERFACE_USBSTOR
#endif //CONFIG_NOTIFICATION
Q_CORE_EXPORT HINSTANCE qWinAppInst();
static inline QStringList drivesFromMask(quint32 driveBits) //driveBits ->unitmask
{
QStringList ret;
#if 1 //a disk with multiple partitions removed
char driveName[] = "A:/";
driveBits &= 0x3ffffff;
while (driveBits) {
if (driveBits & 0x1)
ret.append(QString::fromLatin1(driveName));
++driveName[0];
driveBits >>= 1;
}
return ret;
#else
char i = 0;
for (; i<26; ++i) {
if (driveBits & 0x1)
break;
driveBits >>= 1;
}
QChar c(i + 'A');
return ret << QString(c) + ":";
#endif
}
void static UpdateDevice(PDEV_BROADCAST_DEVICEINTERFACE pDevInf, WPARAM wParam)
{
/*
// dbcc_name:
// \\?\USB#Vid_04e8&Pid_503b#0002F9A9828E0F06#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
// convert to
// USB\Vid_04e8&Pid_503b\0002F9A9828E0F06
ASSERT(lstrlen(pDevInf->dbcc_name) > 4);
wchar_t *szDevId = pDevInf->dbcc_name+4;
int idx = szDevId.ReverseFind(_T('#'));
ASSERT( -1 != idx );
szDevId.Truncate(idx);
szDevId.Replace(_T('#'), _T('\\'));
szDevId.MakeUpper();
CString szClass;
idx = szDevId.Find(_T('\\'));
ASSERT(-1 != idx );
szClass = szDevId.Left(idx);
// if we are adding device, we only need present devices
// otherwise, we need all devices
DWORD dwFlag = DBT_DEVICEARRIVAL != wParam
? DIGCF_ALLCLASSES : (DIGCF_ALLCLASSES | DIGCF_PRESENT);
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, szClass, NULL, dwFlag);
if( INVALID_HANDLE_VALUE == hDevInfo )
{
zDebug("SetupDiGetClassDevs(): " + _com_error(GetLastError()).ErrorMessage());
return;
}
SP_DEVINFO_DATA* pspDevInfoData = (SP_DEVINFO_DATA*)HeapAlloc(GetProcessHeap(), 0, sizeof(SP_DEVINFO_DATA));
pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
for(int i=0; SetupDiEnumDeviceInfo(hDevInfo,i,pspDevInfoData); ++i) {
DWORD DataT ;
DWORD nSize=0 ;
TCHAR buf[MAX_PATH];
if (!SetupDiGetDeviceInstanceId(hDevInfo, pspDevInfoData, buf, sizeof(buf), &nSize)) {
zDebug("SetupDiGetDeviceInstanceId(): " + _com_error(GetLastError()).ErrorMessage());
break;
}
if (szDevId == buf) {
// device found
if (SetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData,
SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize)) {
// do nothing
} else if (SetupDiGetDeviceRegistryProperty(hDevInfo, pspDevInfoData,
SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize)) {
// do nothing
} else {
lstrcpy(buf, _T("Unknown"));
}
// update UI
break;
}
}
if (pspDevInfoData)
HeapFree(GetProcessHeap(), 0, pspDevInfoData);
SetupDiDestroyDeviceInfoList(hDevInfo);
*/
}
/*
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363246%28v=vs.85%29.aspx
typedef struct _DEV_BROADCAST_HDR {
DWORD dbch_size;
DWORD dbch_devicetype;
DWORD dbch_reserved;
} DEV_BROADCAST_HDR, *PDEV_BROADCAST_HDR;
dbch_size:
The size of this structure, in bytes.
If this is a user-defined event, this member must be the size of this header, plus the size of the variable-length data in the _DEV_BROADCAST_USERDEFINED structure.
dbch_devicetype:
The device type, which determines the event-specific information that follows the first three members. This member can be one of the following values.
Value Meaning
DBT_DEVTYP_DEVICEINTERFACE 0x00000005
Class of devices. This structure is a DEV_BROADCAST_DEVICEINTERFACE structure.
DBT_DEVTYP_HANDLE 0x00000006
File system handle. This structure is a DEV_BROADCAST_HANDLE structure.
DBT_DEVTYP_OEM 0x00000000
OEM- or IHV-defined device type. This structure is a DEV_BROADCAST_OEM structure.
DBT_DEVTYP_PORT 0x00000003
Port device (serial or parallel). This structure is a DEV_BROADCAST_PORT structure.
DBT_DEVTYP_VOLUME 0x00000002
Logical volume. This structure is a DEV_BROADCAST_VOLUME structure.
dbch_reserved:
Reserved; do not use.
WM_DEVICECHANGE限制:
1 只有顶层窗体的程序才能收到这个消息
2 仅仅串口、磁盘发生改变,才对每个程序广播这个消息
*/
LRESULT CALLBACK dw_internal_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_DEVICECHANGE) {
DEV_BROADCAST_HDR *lpdb = (DEV_BROADCAST_HDR *)lParam;
zDebug("Device type address: %#x", lpdb);
if (lpdb) {
if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) {
zDebug("DBT_DEVTYP_VOLUME");
} else if (lpdb->dbch_devicetype == DBT_DEVTYP_PORT) {
zDebug("DBT_DEVTYP_PORT");
} else if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
zDebug("DBT_DEVTYP_DEVICEINTERFACE");
} else if (lpdb->dbch_devicetype == DBT_DEVTYP_OEM) {
zDebug("DBT_DEVTYP_OEM");
} else {
zDebug("Unknow device type");
}
}
switch (wParam) {
case DBT_DEVNODES_CHANGED:
zDebug("DBT_DEVNODES_CHANGED message received, no extended info.");
break;
case DBT_QUERYCHANGECONFIG:
zDebug("DBT_QUERYCHANGECONFIG message received, no extended info.");
break;
case DBT_CONFIGCHANGED:
zDebug("DBT_CONFIGCHANGED message received, no extended info.");
break;
case DBT_CONFIGCHANGECANCELED:
zDebug("DBT_CONFIGCHANGECANCELED message received, no extended info.");
break;
case DBT_DEVICEARRIVAL:
case DBT_DEVICEQUERYREMOVE:
case DBT_DEVICEQUERYREMOVEFAILED:
case DBT_DEVICEREMOVEPENDING:
case DBT_DEVICEREMOVECOMPLETE:
if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) {
DEV_BROADCAST_VOLUME *db_volume = (DEV_BROADCAST_VOLUME *)lpdb;
QStringList drives = drivesFromMask(db_volume->dbcv_unitmask);
#ifdef GWLP_USERDATA
QDeviceWatcherPrivate *watcher = (QDeviceWatcherPrivate *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
#else
QDeviceWatcherPrivate *watcher = (QDeviceWatcherPrivate *)GetWindowLong(hwnd, GWL_USERDATA);
#endif
QList<QDeviceChangeEvent *> events;
QString action_str("add");
QDeviceChangeEvent::Action action = QDeviceChangeEvent::Add;
if (wParam == DBT_DEVICEARRIVAL) {
} else if (wParam == DBT_DEVICEQUERYREMOVE) {
} else if (wParam == DBT_DEVICEQUERYREMOVEFAILED)
没有合适的资源?快使用搜索试试~ 我知道了~
多平台QT USB设备热插拔检测库
共23个文件
cpp:8个
png:5个
h:4个
4星 · 超过85%的资源 需积分: 50 163 下载量 177 浏览量
2018-08-24
10:16:11
上传
评论 13
收藏 319KB ZIP 举报
温馨提示
一个很好用的跨平台的USB设备(比如USB鼠标、U盘等)热插拔 QT库。兼容LINUX(Ubuntu),WINDOWS,WINCE,MAC OS。带有终端以及GUI例子,方便运行测试。
资源推荐
资源详情
资源评论
收起资源包目录
qdevicewatcher.zip (23个子文件)
screenshot
win7-gui-debug.png 19KB
wince-emu-gui.PNG 47KB
win7.png 36KB
ubuntu-gui-debug.png 148KB
ubuntu.png 55KB
QDeviceWatcher.pro 326B
test
main_gui.cpp 2KB
hotplugwatcher_gui.pro 455B
hotplugwatcher_gui.cpp 4KB
hotplugwatcher_gui.h 2KB
hotplugwatcher.pro 396B
hotplugwatcher.h 3KB
main.cpp 1KB
src
qdevicewatcher.cpp 3KB
libQDeviceWatcher.pro 589B
qdevicewatcher_win32.cpp 13KB
qdevicewatcher_wince.cpp 4KB
qdevicewatcher_p.h 3KB
libQDeviceWatcher.pri 4KB
qdevicewatcher.h 2KB
qdevicewatcher_linux.cpp 8KB
qdevicewatcher_mac.cpp 3KB
common.pri 16KB
共 23 条
- 1
资源评论
- zlpplz2019-04-10顶顶顶顶顶顶顶顶顶
- fyzy2021-07-01顶顶顶顶顶顶顶顶
- 迷茫的根号七2020-09-13Windows10下 拿到的信息都是0x00
- sanqima2020-06-14学习多平台USB编程的好资源,值得一看。
- Huige3522021-08-25Mac 环境下直接挂掉,运行不起来,尴尬了。。。
wangrui_123168
- 粉丝: 1
- 资源: 10
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功