Detecting USB Insertion / Removal Events in Windows using C++

后端 未结 4 2044
悲&欢浪女
悲&欢浪女 2020-11-30 02:38

I am writing an extension for an existing application that needs to handle USB insertion/removal events. I know the VID/PID of the device of interest. However, I don\'t ha

相关标签:
4条回答
  • 2020-11-30 03:00

    There is a MSDN sample specifically for your case, in native code.

    Registering for Device Notification

    Better to do it this way than via WMI.

    0 讨论(0)
  • 2020-11-30 03:10

    This is another way for detecting the INSERTION & REMOVAL of USB storage devices.

    This c++ code detect INSERTION and REMOVAL both of USB Storage devices.

    This also detect Multiple insertion and removal of USB devices at same time.

    c++ code: Tested in VISUAL STUDIO 2015

    You can also check for other types of devices for removal and insertion. Just fill passed char array to other types of devices in if else of the code in function getUSBStorageDeviceList()

        #include "stdafx.h"
        #include <stdio.h>
        #include <time.h>
        #include <windows.h>
        #include <string>
        #include<iostream>
    
        using namespace std;
    
        #define MAX_LETTER 26
        char PREV_DRIVE_LIST[MAX_LETTER];
        char NEW_DRIVE_LIST[MAX_LETTER];
    
        /* To GET DRIVE LIST in char ARRAY */
        void getUSBStorageDeviceList(char drive[]) {
    
            int count = 0;
    
            char szLogicalDrives[MAX_PATH];
            size_t size = strlen(szLogicalDrives) + 1;
            wchar_t* text = new wchar_t[size];
    
            size_t outSize;
            mbstowcs_s(&outSize, text, size, szLogicalDrives, size - 1);
    
            DWORD dwResult = GetLogicalDriveStrings(MAX_PATH, text); // text = szLogicalDrives
            WCHAR* szSingleDrive = text;
    
            while (*szSingleDrive)
            {
                UINT nDriveType = GetDriveType(szSingleDrive);
    
            //  printf("\nFUNC: getRemovableDisk, Drive Name%d= %s", ++count, szSingleDrive);
    
                if (nDriveType == DRIVE_UNKNOWN) {
                //  cout << "\nDrive type : Unknown: The drive type cannot be determined." << endl;
                }
                else if (nDriveType == DRIVE_NO_ROOT_DIR) {
                //  cout << "\nDrive type : Invalid Root Directory Media: The root path is invalid." << endl;
                }
                else if (nDriveType == DRIVE_REMOVABLE) {
                //  cout << "\nDrive type :  Removable Media:" << endl;
                    char letter = szSingleDrive[0];
                    drive[letter - 65] = letter;
                }
                else if (nDriveType == DRIVE_FIXED) {
                    //cout << "\nDrive type : Fixed Media: " << endl;
                }
                else if (nDriveType == DRIVE_REMOTE) {
                    //cout << "\nDrive type : Remote Media: The drive is a remote (network) drive.." << endl;
                }
                else if (nDriveType == DRIVE_CDROM) {
                    //cout << "\nDrive type : CD ROM:   The drive is a CD-ROM drive." << endl;
                }
                else if (nDriveType == DRIVE_RAMDISK) {
                    //cout << "\nDrive type : RAM Disk: The drive is a RAM disk." << endl;
                }
    
                szSingleDrive += wcslen(szSingleDrive) + 1; // next drive 
            }
        }
    
        int main(void) {
    
            int count = 0;
            for (int i = 0; i < MAX_LETTER; i++) {
                PREV_DRIVE_LIST[i] = '0';
                NEW_DRIVE_LIST[i] = '0';
            }
            // initial drive list which is already attached 
            getUSBStorageDeviceList(PREV_DRIVE_LIST);
    
            while (1) {
    
                getUSBStorageDeviceList(NEW_DRIVE_LIST);
                count = 1;
    
                /* Check for insertion and removabal*/
    
                for (int i = 0; i < MAX_LETTER; i++) {
                    // check for new drive
                    if ((NEW_DRIVE_LIST[i] >= 65 && NEW_DRIVE_LIST[i] <= 89) && (PREV_DRIVE_LIST[i] == '0')) {
    
                        printf("\nNew Device Inserted%d : %c", count++, NEW_DRIVE_LIST[i]);
                        PREV_DRIVE_LIST[i] = NEW_DRIVE_LIST[i];
                    }
                }
                    // fill ALl zero 
                    for (int i = 0; i < MAX_LETTER; i++) {
                        NEW_DRIVE_LIST[i] = '0';
                    }
                    // update NEW drive list
                    getUSBStorageDeviceList(NEW_DRIVE_LIST);
    
                    for (int i = 0; i < MAX_LETTER; i++) {
                        // check for removed drive
                        if ((PREV_DRIVE_LIST[i] >= 65 && PREV_DRIVE_LIST[i] <= 89) && (NEW_DRIVE_LIST[i] == '0')) {
                            printf("\nDevice Removed%d : %c", count++, PREV_DRIVE_LIST[i]);
                            PREV_DRIVE_LIST[i] = NEW_DRIVE_LIST[i];
                        }
                }
                    Sleep(500);
            }
    
            return 0;
        }
    

    REMARK : This does not create Any windows. This is console Application.

    0 讨论(0)
  • 2020-11-30 03:20

    Create a dummy window that does nothing but wait for WM_DEVICECHANGE and register that window using RegisterDeviceNotification. WMI is an overkill here, IMHO.

    0 讨论(0)
  • 2020-11-30 03:22

    I followed your "new approach" and also found that OnDeviceChange wasn't being called. The problem was that there was no message loop because it was a Console app. Calling the following function at regular intervals fixed it.

    void check_for_device_change()
    {
        MSG msg; 
    
        const int val = PeekMessage( &msg, 0, 0, 0, PM_REMOVE );
    
        if( val > 0 )
        { 
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        } 
    }
    
    0 讨论(0)
提交回复
热议问题