I am trying to write a little backup program for friends and family and want it to be as simple to use a possible. I don\'t want to have to ask the user where to backup thei
You need to use RegisterDeviceNotification function. Here is some pointers about how to do it. And one more sample code
You can enumerate all mass storage devices using this sample. In General look for SetupDiXXX api's.
Please note that taking in consideration dynamic nature of usb devices, using notification mechanism is mandatory IMHO. You might find your self analyzing device that already detached or missing new device that just arrived.
A few pieces of information can be gathered without too much trouble:
Post your answer here when you find it!
-Adam
I spent a little time looking around and found a function called SetupDiEnumDeviceInfo which did provide a solution to know whether a hard drive was removable or not but with that information I still can't (yet) map what I find back to a drive letter!
Here's what I have so far (following code creates a dll):
#include "stdafx.h"
#include <setupapi.h>
#include <devguid.h>
#include <cfgmgr32.h>
extern "C" __declspec(dllexport) int usb_hard_drives() {
HDEVINFO hdevinfo = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT);
if (hdevinfo == INVALID_HANDLE_VALUE) return -1;
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);
int c = 0;
while (SetupDiEnumDeviceInfo(hdevinfo, MemberIndex, &sp_devinfo_data)) {
DWORD PropertyRegDataType;
DWORD RequiredSize;
DWORD PropertyBuffer;
if (SetupDiGetDeviceRegistryProperty(hdevinfo, &sp_devinfo_data, SPDRP_CAPABILITIES, &PropertyRegDataType, (PBYTE)&PropertyBuffer, sizeof(PropertyBuffer), &RequiredSize)) {
if (PropertyBuffer && CM_DEVCAP_REMOVABLE == CM_DEVCAP_REMOVABLE) {
// do something here to identify the drive letter.
c++;
}
}
MemberIndex++;
}
SetupDiDestroyDeviceInfoList(hdevinfo);
return c;
}
I know your question is tagged Win32, but this is quite simple with .NET:
foreach (IO.DriveInfo drive in IO.DriveInfo.GetDrives()) {
if ((drive.DriveType == IO.DriveType.Removable)) {
// this is a removable drive
}
}
See drive.Name and drive.VolumeLabel for getting the label. You can also get the size, and make an educated guess that it's a USB stick (and a big enough one) -- Removable can mean either Floppy or USB, according to the docs.
As a side note, from a UI perspective, I'd suggest the first time you find a new drive, present it to the user and ask "is this the drive you want to use for backups?". Otherwise, there is a big potential for accidentally wiping out data on a usb key that happened to be plugged in. Nothing destroys the credibility of a backup program like when it destroys your data. :)
I found a great function in the Win32 API for testing the type of drive.
if( 2 == ::getDriveType( <driveletter> )){
// its removable
}
Return values of function:
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.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx