Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if exe is running from a USB

Tags:

c++

c

windows

I am writing an app using windows API that needs to check on startup that it is running from a USB device. What I have achieved so far

  • List devices using SetupDiEnumDeviceInfo
  • Detecting which device is removable

Here is my code to do the above 2 tasks

HDEVINFO hdevinfo = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE,NULL, NULL, DIGCF_PRESENT);
if (hdevinfo == INVALID_HANDLE_VALUE) {
    WriteLog(L"hdevinfo is INVALID_HANDLE_VALUE");
    return USB_PROT_ERROR;
}
DWORD MemberIndex = 0;
SP_DEVINFO_DATA sp_devinfo_data;
ZeroMemory(&sp_devinfo_data, sizeof(sp_devinfo_data));
sp_devinfo_data.cbSize = sizeof(sp_devinfo_data);
while (SetupDiEnumDeviceInfo(hdevinfo, MemberIndex, &sp_devinfo_data)) {
    DWORD PropertyRegDataType;
    DWORD RequiredSize;
    TCHAR PropertyBuffer[500];
    //get the name of this device
    if (SetupDiGetDeviceRegistryProperty(hdevinfo, &sp_devinfo_data, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, &PropertyRegDataType, (PBYTE)&PropertyBuffer, sizeof(PropertyBuffer), &RequiredSize)) {
        WriteLog(L"Device name: %s", PropertyBuffer);
        DWORD PropertyValue;
        //get removal policy for this device
        if (SetupDiGetDeviceRegistryProperty(hdevinfo, &sp_devinfo_data, SPDRP_REMOVAL_POLICY, &PropertyRegDataType, (PBYTE)&PropertyValue, sizeof(PropertyValue), &RequiredSize)) {
            if (PropertyValue == CM_REMOVAL_POLICY_EXPECT_NO_REMOVAL) {
                //not removable
                WriteLog(L"Not Removable");
            }
            else {
                //removable
                WriteLog("Removable");
            }
        }
    }
}

On my PC with 1 HARD DRIVE and 1 USB DRIVE attached, I get this output:

Device name: \Device\00000031
Not Removable

Device name: \Device\00000070
Removable

From the output it is clear that \Device\00000070 is my USB device. And from My Computer I can see that my USB device is mounted on H drive

What I want to achieve now is

  • Find out that on which drive letter (in my case it is H:) that removable device (in my case it is \Device\00000070) is mounted.

OR

  • Find out all the volumes(sub devices I can say) that are under this device. For example if I pass GUID_DEVCLASS_VOLUME GUID to SetupDiGetClassDevs function then my output looks like this:

    Device name: \Device\HarddiskVolume2 Not Removable

    Device name: \Device\HarddiskVolume4 Not Removable

    Device name: \Device\HarddiskVolume9 Not Removable

    Device name: \Device\HarddiskVolume5 Not Removable

After some debugging I found that \Device\HarddiskVolume9 is my USB but you can see in the output that it always show "Not Removable". So if I can find out that \Device\HarddiskVolume9 belongs to \Device\00000070 then that will also work for me as I can then easily use Volume management functions to find the drive letter for \Device\HarddiskVolume9 and match with the drive letter of the executable.

I want to do this using C/C++ Windows API without using any 3rd party library and no .NET code.

like image 553
Rameez Usmani Avatar asked Aug 06 '20 13:08

Rameez Usmani


People also ask

How can I see which process is using my USB?

Just select the Find menu and select Find Handle or DLL . In the dialog that opens enter the drive letter into the search box. The search results should show all of the files that are open from the drive and which process has them open.

What program is using my device?

Open the Windows Device Manager by searching for 'Device Manager' in the Windows taskbar. In the Device Manager, locate your device, right click on it and select Properties. In the Properties window, select the Details tab. From the Property drop-down menu, select Physical Device Object name.

How do I know if someone has accessed my USB drive?

Depending on how many files you have on the USB, what you can do is right-click on the files and click properties. There it should give you information about the file such as when it was created, last modified, and last accessed.

Why won't my computer let me eject my USB?

Why Windows Can't Eject the USB Drive. The most common cause for Windows's inability to eject an external storage device is that your system is still accessing the files or folders on that device. Even if there's no obvious process such as copying a file, there could be a background process still running.

How do I find out what stopped my USB from ejecting?

Double-click the most recent event to view its details. The details for the event show which app or process it was that kept the USB from ejecting. Look in the ‘General’ tab and the event will describe what prevented the USB from being stopped. It’s not going to highlight the exact app or process for you.

How do I know if an app is using a USB?

There are apps available that can detect which app or process is using a USB but Windows has a built-in tool that can do this. It’s called Event Viewer. Event Viewer is an app that logs all activities, both user and system, as and when they happen.

Why can’t i remove a USB drive from my computer?

At times, Windows tells you it isn’t safe to remove a USB drive because it is in use by an app or a process. The message prompt doesn’t tell you which app or process is using a USB. Here’s how you can see what’s preventing Windows from safely ejecting a USB drive.

How do I run software from a USB flash drive?

Windows users can run software from a USB flash drive by installing a "Platform" from PortableApps.com where they can search for and install apps. Mac users can search and directly install apps to a USB drive via Source Forge. You may wish to run software directly from a USB flash drive...


1 Answers

Windows API function GetDriveType returns the following:

DRIVE_UNKNOWN - 0 - The drive type cannot be determined.

DRIVE_NO_ROOT_DIR - 1 - The root path is invalid; for example, there is no volume mounted at the specified path.

DRIVE_REMOVABLE - 2 - The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.

DRIVE_FIXED - 3 - The drive has fixed media; for example, a hard disk drive or flash drive.

DRIVE_REMOTE - 4 - The drive is a remote (network) drive.

DRIVE_CDROM - 5 - The drive is a CD-ROM drive.

DRIVE_RAMDISK - 6 - The drive is a RAM disk.

So I would use the following code, checking if the return value is equal to (2) - Removable:

#include <windows.h>
int main()
{
    wchar_t basePath[1024]{ L"" }, volName[1024]{ L"" };
    GetModuleFileName(NULL, basePath, 1024);
    GetVolumePathName(basePath, volName, 1024);

    UINT type = GetDriveType(volName);
    if (type == 2)
    {
        MessageBox(NULL, L"You are running from a flash drive (USB)",L"",MB_OK);
    }
    else
    {
        MessageBox(NULL, L"You are NOT running from a flash drive (USB)",L"", MB_OK);

    }
}
like image 173
Michael Haephrati Avatar answered Sep 29 '22 08:09

Michael Haephrati