[core] detect memory cards in card readers

* Also remove drives with no media from the list
* Closes #18
This commit is contained in:
Pete Batard 2013-12-20 18:32:10 +00:00
parent 897becd290
commit 36693d2144
6 changed files with 75 additions and 9 deletions

View File

@ -450,6 +450,23 @@ uint64_t GetDriveSize(DWORD DriveIndex)
return DiskGeometry->DiskSize.QuadPart;
}
/*
* GET_DRIVE_GEOMETRY is used to tell if there is an actual media
*/
BOOL IsMediaPresent(DWORD DriveIndex)
{
BOOL r;
HANDLE hPhysical;
DWORD size;
BYTE geometry[128];
hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE);
r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
NULL, 0, geometry, sizeof(geometry), &size, NULL) || (size <= 0);
safe_closehandle(hPhysical);
return r;
}
/*
* Fill the drive properties (size, FS, etc)
*/

View File

@ -1243,7 +1243,7 @@ DWORD WINAPI FormatThread(LPVOID param)
// Try to ensure that all messages from Format and Checkdisk, which we report in the log, will be in English
pfSetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
if (PRIMARYLANGID(pfGetThreadUILanguage()) != LANG_ENGLISH)
uprintf("Note: the formatting thread could not be set to English");
uprintf("Note: some formatting messages may still be localized");
PrintStatus(0, TRUE, MSG_225);
hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE);

View File

@ -134,7 +134,6 @@ static BOOL htab_create(uint32_t nel)
nel += 2;
htab_size = nel;
uprintf("localization: using %d entries hash table\n", nel);
htab_filled = 0;
// allocate memory and zero out.

View File

@ -31,6 +31,7 @@
#include <commctrl.h>
#include <setupapi.h>
#include <winioctl.h>
#include <shlobj.h>
#include <process.h>
#include <dbt.h>
#include <io.h>
@ -65,7 +66,7 @@
#define DBT_CUSTOMEVENT 0x8006
#endif
// MinGW fails to link those
// MinGW fails to link those...
typedef HIMAGELIST (WINAPI *ImageList_Create_t)(
int cx,
int cy,
@ -86,6 +87,25 @@ struct {
UINT uAlign;
} bi_iso = {0}, bi_up = {0}, bi_down = {0}, bi_lang = {0}; // BUTTON_IMAGELIST
// ...and MinGW doesn't know these.
typedef struct
{
LPCITEMIDLIST pidl;
BOOL fRecursive;
} MY_SHChangeNotifyEntry;
typedef BOOL (WINAPI *SHChangeNotifyDeregister_t)(
ULONG ulID
);
typedef ULONG (WINAPI *SHChangeNotifyRegister_t)(
HWND hwnd,
int fSources,
LONG fEvents,
UINT wMsg,
int cEntries,
const MY_SHChangeNotifyEntry *pshcne
);
const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT" };
// Number of steps for each FS for FCC_STRUCTURE_PROGRESS
const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10 };
@ -745,6 +765,13 @@ static BOOL GetUSBDevices(DWORD devnum)
}
drive_index = device_number.DeviceNumber + DRIVE_INDEX_MIN;
if (!IsMediaPresent(drive_index)) {
uprintf("Device eliminated because it appears to contain no media\n");
safe_closehandle(hDrive);
safe_free(devint_detail_data);
break;
}
if (GetDriveLabel(drive_index, &drive_letter, &label)) {
if ((!enable_HDDs) && ((score = IsHDD(drive_index, vid, pid, buffer)) > 0)) {
uprintf("Device eliminated because it was detected as an USB Hard Drive (score %d > 0)\n", score);
@ -1512,10 +1539,18 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
char tmp[128];
static UINT uBootChecked = BST_CHECKED, uQFChecked;
static BOOL first_log_display = TRUE, user_changed_label = FALSE;
static ULONG ulRegister = 0;
static LPITEMIDLIST pidlDesktop = NULL;
static MY_SHChangeNotifyEntry NotifyEntry;
loc_cmd* lcmd = NULL;
PF_DECL(SHChangeNotifyRegister);
PF_DECL(SHChangeNotifyDeregister);
switch (message) {
case UM_MEDIA_CHANGE:
wParam = DBT_CUSTOMEVENT;
// Fall through
case WM_DEVICECHANGE:
// The Windows hotplug subsystem sucks. Among other things, if you insert a GPT partitioned
// USB drive with zero partitions, the only device messages you will get are a stream of
@ -1528,7 +1563,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
switch (wParam) {
case DBT_DEVICEARRIVAL:
case DBT_DEVICEREMOVECOMPLETE:
case DBT_CUSTOMEVENT: // This last event is sent by our timer refresh function
case DBT_CUSTOMEVENT: // Sent by our timer refresh function or for card reader media change
LastRefresh = GetTickCount(); // Don't care about 49.7 days rollback of GetTickCount()
KillTimer(hMainDialog, TID_REFRESH_TIMER);
GetUSBDevices((DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList)));
@ -1549,6 +1584,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
break;
case WM_INITDIALOG:
PF_INIT(SHChangeNotifyRegister, shell32);
apply_localization(IDD_DIALOG, hDlg);
SetUpdateCheck();
advanced_mode = TRUE;
@ -1559,6 +1595,15 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
InitDialog(hDlg);
GetUSBDevices(0);
CheckForUpdates(FALSE);
// Register MEDIA_INSERTED/MEDIA_REMOVED notifications for card readers
if ((pfSHChangeNotifyRegister != NULL) && (SUCCEEDED(SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &pidlDesktop)))) {
NotifyEntry.pidl = pidlDesktop;
NotifyEntry.fRecursive = TRUE;
// NB: The following only works if the media is already formatted.
// If you insert a blank card, notifications will not be sent... :(
ulRegister = pfSHChangeNotifyRegister(hDlg, 0x0001|0x0002|0x8000,
SHCNE_MEDIAINSERTED|SHCNE_MEDIAREMOVED, UM_MEDIA_CHANGE, 1, &NotifyEntry);
}
PostMessage(hMainDialog, UM_ISO_CREATE, 0, 0);
return (INT_PTR)TRUE;
@ -1600,6 +1645,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
switch(LOWORD(wParam)) {
case IDOK: // close application
case IDCANCEL:
PF_INIT(SHChangeNotifyDeregister, shell32);
EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), FALSE);
EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
if (format_thid != NULL) {
@ -1622,6 +1668,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
}
return (INT_PTR)TRUE;
}
if ((pfSHChangeNotifyDeregister != NULL) && (ulRegister != 0))
pfSHChangeNotifyDeregister(ulRegister);
PostQuitMessage(0);
StrArrayDestroy(&DriveID);
StrArrayDestroy(&DriveLabel);

View File

@ -109,6 +109,7 @@ extern void _uprintf(const char *format, ...);
/* Custom Windows messages */
enum user_message_type {
UM_FORMAT_COMPLETED = WM_APP,
UM_MEDIA_CHANGE,
// TODO: relabel "ISO" to a more generic "progress"
UM_ISO_CREATE,
UM_ISO_INIT,
@ -329,6 +330,7 @@ extern BOOL DeletePartitions(HANDLE hDrive);
extern const char* GetPartitionType(BYTE Type);
extern BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize);
extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label);
extern BOOL IsMediaPresent(DWORD DriveIndex);
extern BOOL MountVolume(char* drive_name, char *drive_guid);
extern BOOL UnmountVolume(HANDLE hDrive);
extern BOOL RemountVolume(char* drive_name);

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Rufus v1.4.2.359"
CAPTION "Rufus v1.4.2.360"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,291,50,14
@ -288,8 +288,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,2,359
PRODUCTVERSION 1,4,2,359
FILEVERSION 1,4,2,360
PRODUCTVERSION 1,4,2,360
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -306,13 +306,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.4.2.359"
VALUE "FileVersion", "1.4.2.360"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2013 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.4.2.359"
VALUE "ProductVersion", "1.4.2.360"
END
END
BLOCK "VarFileInfo"