Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Monitoring Removable Storage Devices in Qt on Windows

Tech May 14 13

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...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

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