Recognize if removable drive was inserted - c++

I have a piece of code to check the removable drives connected to the computer. But I have to check when the drive is available or inserted into the USB port.Should I write a while loop constantly checking for the drive with certain ID to become available? If I make it into a windows service, do I have to do the same i.e keep looping until the device is found?

Create a hidden window and use it to listen for WM_DEVICECHANGE messages.
Whatever you do, don't poll. That's horribly wasteful and inefficient.

You could use WMI (from C++ this will mean using WMI's COM API): creation events for the Win32_LogicalDisk class.

Related

Programmatically Eject USB Device while it is in use

How can i programmatically eject USB Device even if it is in use?
Scenarios:
USB device attached to the system.
We get WM_DEVICECHANGE message by "RegisterDeviceNotification" through which we can handle events like DBT_DEVICEARRIVAL, DBT_DEVICEQUERYREMOVE etc.
Now if the device is in use, if we want to eject it from explorer, it prompts as "Problem Ejecting USB Mass Storage Device "This device is currently in use. Close any programs or windows that might be using the device, and then try again."
Question: 1: How can we eject USB without any prompt while it is in use?
Question: 2: How can we get notification when the user press eject from explorer for USB device ?
Thanks in advance :)
Well, you can't mechanically eject it. So what does it mean to software-eject it? It means that Windows will prevent any further handles to be created for files or directories. As a result, it's safe to remove the USB stick afterwards
Now what does it mean that the USB stick is in use? That just means there are open handles. It doesn't make a difference whether you prevent any further handles from being created. Removing a USB stick while there's a handle open means that you risk corrupting the content on the USB stick.
Therefore, it's not a matter of wanting to ejecting the USB stick while in use. The question simply makes no sense at all.
Note that Windows already tells you what you should in fact do: Close any programs or windows that might be using the device, and then try again.
Question two similarly does not make a lot of sense either. When disk F: is gone, why should you care about the details? After all, if you had reasons to care (e.g. open file), Windows would have blocked that operation.

Auto run when USB plugged in

Is it possible to make a program auto run (execute) when the USB it is stored on is plugged into a computer
I don't think this is possible due to the searching I have looked at on the Internet and also the security risk such coding would have
E.g. I have a simple countdown timer (10 to 1) programmed in C++ (complied on windows), when the USB (which the .exe file is stored on) is plugged into a computer the timer will start without me executing it manually.
You can create an Autorun.inf file and place it on the USB drive. Windows will read this file when the drive is connected. In the file you can specify the name of the program you'd like to run, as well as icons, etc.
You cannot force the program to run when the USB drive is inserted. That's up to the security policy of the operating system, and most will at least prompt the user "Do you want to run 'Setup.exe' from this drive?" or something like that.
By default it's not possible, since Windows puts users in control of their computers as much as possible—if they don't want autorun enabled, it will not be possible to have a program executed automatically.
You could write a helper program that runs in the background (possibly as a service) that sleeps most of the time, waiting for a USB device to be plugged in. There might be a way to receive notifications of this, or you might just have to poll it periodically, I don't know. Once it detects a USB device, it can then of course do whatever it wants (CreateProcess etc.).
Since Windows 7, the autorun.inf file is ignored when it comes to USB devices. U3 technology allows a thumb drive to be treated as a CD/DVD which might be a possible solution.
I think you can do so using system(), if you are familiar with disktype command in cmd, then I think you can figure things out. All what you can do in command prompt you can also do in c++ using system(). But it will consume alot of memory space

Path to a USB Device in Windows

I would be using a USB hub to connect multiple devices. I want to fix a specific USB device to a particular slot. Then check if it is done properly.
The way I am planning to achieve this is to get the complete USB path like
PCIROOT(0)#PCI(1D00)#USBROOT(0)#USB(1)#USB(2)#USB(3)#USB(3)
I can get this particular string in w7 via device property but the same is not available in wXP.
You can build this path by using the SetupAPI.
The device manager is built with this.
You start with CM_Locate_DevNode and enumerate children with CM_Get_Child.
I strongly advise you against what you're planning to do. AFAIK a USB device MUST function regardless on the USB port it's plugged in. If you'll creating such a device, forget e.g. about the "Certified for Windows" logo.
Just handle WM_DEVICECHANGE message, then use e.g. WMI to search for the USB device you're interested in. Here's my article about it: that time I coded C# language, however WMI has C++ API as well.

How can I determine the type of a particular drive?

I feel somewhat noob yet with this of getting the Information of Hardware of the CPU, so i come with this request: Hard Drive, CD/DVD/Bluray reader, Floppy and if it's possible USB.
I've been looking on MSDN GetDriveType but seems i'm bad at searching or i don't understand it. Any idea?
I'm not sure what you didn't understand about the documentation you linked to...
The sole argument accepted by the function is the root directory of the drive you want to get information about (including a trailing backslash). The function returns a value indicating which type of drive that is. A chart is shown that gives the possible return values and what each of them mean.
For example:
GetDriveType(_T("C:\\")) // returns DRIVE_FIXED if C:\ is my hard drive
GetDriveType(_T("A:\\")) // returns DRIVE_REMOVABLE if A:\ is my floppy drive
GetDriveType(_T("D:\\")) // returns DRIVE_CDROM if D:\ is a CD-ROM drive
GetDriveType(_T("N:\\")) // returns DRIVE_REMOTE if N:\ is a network drive
It also says that if you want to determine whether a drive is a USB-type drive, you need to call the SetupDiGetDeviceRegistryProperty function and specify the SPDRP_REMOVAL_POLICY property.
If you want to determine that a device is USB device, you can open its handle and send IOCTL queries using DeviceIoControl() to get bus type a device is connected to.
EnumUsbDrivesLetters - the post is in Russian but it contains C++ source code, so the matter could be understood easily.
Cheers, Andriy
The only all-in-one API I know of for Windows with that information is WMI, but it's not terribly simple to use. On the other hand, many programs communicate with devices directly, using pass-through control codes, or I/O control codes like SMART_RCV_DRIVE_DATA.
(I don't know how Speccy works, but I'm guessing it uses a combination of these methods to get the system info needed.)

Programmatically differentiating between USB Floppy Drive and USB Flash Drive in Windows

On Windows (XP-7), is there a reliable way of programatically differentiating between USB floppy drives and USB flash drives in C++?
At the moment, I'm using WMI to get updates when new Win32_LogicalDisk instances are detected, and then using the DriveType attribute of the LogicalDisk object to figure out a basic type. This works quite well, except that floppy drives and USB flash drives are both of DriveType DRIVE_REMOVABLE, so to differentiate between those (floppy vs. flash), I'm using the IOCTL_STORAGE_GET_HOTPLUG_INFO interface to figure out if the device is hotpluggable, and was working on the principal that that meant it was a flash drive and not a floppy. Again, I think this works quite well (if a little inefficient, using both the WDK API and WMI to get info ) in the case of internal floppy drives, but unfortunately USB Floppy drives are also hotpluggable a lot of the time, so there is no clear way to differentiate between flash and USB floppy drives, that I can see. I know there are properties that may work, like checking if its mapped to the reserved drives A: or B (edit: only relevant if the machine definitely has a floppy drive - see MS-KB: How to change drive letter assignments in Windows XP), or looking at the description, but I'd really like something a bit more reliable.
Sorry about the long explanation, but just wanted to be clear! Thanks
Did you try Win32_LogicalDisk.MediaType? It has specific enumerations for floppy disks. Make sure you try it when there's no disk in the drive.
On the USB level, there is no way to differentiate between a conventional Disk on Key and a USB-Floppy. Which means windows itself, cannot tell reliably what is what.
There are a few hints that you can gather:
Floppies should:
a. Have mass-storage protocol CBI/CB
b. SCSI UFI
BUT, in the world of USB devices, everyone does whatever they want. The only test is: "Does it work on windows". And Windows just checks the size, if its a USB device with removable-media set and with conventional floppy sizes, it will consider it to be a floppy.
Can't say about "real" floppy, but with the USB attached, there is no definite way.
You can use the Size attribute (USB > 1.4MB), it's not like there is any chance of meeting 1.4MB flash drive any time soon.
The obvious property to check would be IOCTL_DISK_GET_DRIVE_GEOMETRY. This gets you (amongst other things) a MEDIA_TYPE. Anything but RemovableMedia and FixedMedia is a floppy.