Surjya Narayana Padhi
Surjya Narayana Padhi

Reputation: 7841

Detecting USB notification in Qt on windows

In my qt application I want to save some application output data to an file in my usb pen drive. I need to put following features in my qt application

  1. Detect the usb drive insertion
  2. I have only one usb slot.
  3. After i insert it I want to know its drive number and letter and transfer a file at specific location in my PC to that usb drive.

Can anybody tell me which winapi .lib , .h and .dll file i hav to use to get all the above functionalities ?

If someone can provide some code snippets, it will very much helpful for me.

Upvotes: 4

Views: 8071

Answers (2)

Captain Normal
Captain Normal

Reputation: 471

The earlier answer is now out-of-date. The following worked for me with QT5 on Windows 10, where MainWindow is derived from QMainWindow:

#include <QByteArray>
#include <windows.h>
#include <dbt.h>

bool MainWindow::nativeEvent(const QByteArray& eventType, void* pMessage, long* pResult)
{
    auto pWindowsMessage = static_cast<MSG*>(pMessage);
    auto wParam = pWindowsMessage->wParam;
    if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) {
        auto lParam = pWindowsMessage->lParam;
        auto deviceType = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam)->dbch_devicetype;
        if (deviceType == DBT_DEVTYP_VOLUME) {
            auto unitmask = reinterpret_cast<DEV_BROADCAST_VOLUME*>(lParam)->dbcv_unitmask;
            for (int i = 0; i < 32; ++i) {
                if ((unitmask & (1 << i)) != 0) {
                    setDriveChanged('A' + i, wParam == DBT_DEVICEARRIVAL);
                }
            }
        }
    }
    return false;
}

Upvotes: 2

Erik
Erik

Reputation: 91260

Handle WM_DEVICECHANGE - See http://lists.trolltech.com/qt-interest/2001-08/thread00698-0.html for how to handle windows messages in QT.

If wParam is DBT_DEVICEARRIVAL then cast lParam to a DEV_BROADCAST_HDR *

If the structures dbch_devicetype is DBT_DEVTYP_VOLUME cast lParam again, this time to a DEV_BROADCAST_VOLUME *

Now check the dbcv_unitmask bit field, iterate over bits 0..31 and check if the corresponding drive match your USB drive.

if (wParam == DBT_DEVICEARRIVAL) {
  if (((DEV_BROADCAST_HDR *) lParam)->dbch_devicetype == DBT_DEVTYP_VOLUME) {
    DWORD Mask = ((DEV_BROADCAST_VOLUME *) lParam)->dbcv_unitmask;
    for (int i = 0; i < 32; ++i) {
      if (Mask & (1 << i)) {
        char RootPath[4] = "A:\\";
        RootPath[0] += i;
        // Check if the root path in RootPath is your USB drive.
      }
    }
  }
}

Upvotes: 3

Related Questions