Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Monitoring Removable Storage Devices in Qt on Windows

Tech May 14 2

Developing a custom file browser requires real-time awareness of system storage changes, such as USB flash drive insertions or remvoals. On Windows, this is achieved by interceptign system-level device notifications. The most effective way to monitor these changes in a Qt application is by handling the WM_DEVICECHANGE message.

1. Handling WM_DEVICECHANGE

When a hardware configuration change occurs, Windows broadcasts the WM_DEVICECHANGE message to top-level windows. Key event codes include:

  • DBT_DEVICEARRIVAL: A new device has been connected and is ready for use.
  • DBT_DEVICEREMOVECOMPLETE: A device has been physically removed or disconnected.
  • DBT_DEVNODES_CHANGED: Triggered whenever a device is added or removed, though it may fire multiple times per action.

2. Registering for Device Notifications

To monitor specific volumes, use the RegisterDeviceNotification Win32 API. This registers your application to receive notifications for specific device handles or interface classes.


bool DeviceMonitor::registerDriveForNotification(const QString &drivePath) {
    // Ensure the drive exists before registration
    DWORD mask = GetLogicalDrives();
    int index = drivePath.at(0).toUpper().toLatin1() - 'A';
    if (!(mask & (1 << index))) return false;

    // Open a handle to the volume
    HANDLE hDrive = CreateFile(
        (L"\\\\.\\" + drivePath.left(2)).toStdWString().c_str(),
        GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL
    );

    if (hDrive == INVALID_HANDLE_VALUE) return false;

    DEV_BROADCAST_HANDLE filter = {0};
    filter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
    filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
    filter.dbch_handle = hDrive;

    HDEVNOTIFY hNotify = RegisterDeviceNotification(
        (HWND)this->winId(), &filter, DEVICE_NOTIFY_WINDOW_HANDLE
    );

    CloseHandle(hDrive);
    return (hNotify != NULL);
}

3. Intercepting Events in Qt

The most efficient way to capture these native Windows events within a Qt application is by implementing the QAbstractNativeEventFilter interface. By installing this filter onto the QCoreApplication, you can examine every incoming message before it is processed by Qt's event loop.


bool DeviceEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) {
    if (eventType == "windows_dispatcher_MSG" || eventType == "windows_generic_MSG") {
        MSG *msg = static_cast<msg>(message);
        
        if (msg->message == WM_DEVICECHANGE) {
            PDEV_BROADCAST_HDR header = reinterpret_cast<pdev_broadcast_hdr>(msg->lParam);
            
            switch (msg->wParam) {
                case DBT_DEVICEARRIVAL:
                    if (header->dbch_devicetype == DBT_DEVTYP_VOLUME) {
                        emit deviceInserted();
                    }
                    break;
                case DBT_DEVICEREMOVECOMPLETE:
                    if (header->dbch_devicetype == DBT_DEVTYP_VOLUME) {
                        emit deviceRemoved();
                    }
                    break;
            }
        }
    }
    return false; // Continue event propagation
}
</pdev_broadcast_hdr></msg>

To activate the filter, call qApp->installNativeEventFilter(filterInstance) during application initialization. This architecture ensures that your UI remains responsive and automatically detects changes in connected external storage devices without requiring polling mechanisms.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Comprehensive Guide to Hive SQL Syntax and Operations

This article provides a detailed walkthrough of Hive SQL, categorizing its features and syntax for practical use. Hive SQL is segmented into the following categories: DDL Statements: Operations on...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.