diff --git a/resource.h b/resource.h index 5211a93f..d34f8387 100644 Binary files a/resource.h and b/resource.h differ diff --git a/usbdos.c b/usbdos.c index cfbfe532..817a93e9 100644 --- a/usbdos.c +++ b/usbdos.c @@ -28,6 +28,10 @@ #include // TODO: MinGW32 requires #include +// http://doc.sch130.nsc.ru/www.sysinternals.com/ntw2k/source/fmifs.shtml +// http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fmifs/ +//#include +// http://git.kernel.org/?p=fs/ext2/e2fsprogs.git;a=blob;f=misc/badblocks.c #include "msapi_utf8.h" #include "resource.h" @@ -37,7 +41,7 @@ * Globals */ static HINSTANCE main_instance; -static HWND hDeviceList; +static HWND hDeviceList, hCapacity; #ifdef USBDOS_DEBUG static void _uprintf(const char *format, ...) @@ -96,59 +100,136 @@ static char err_string[256]; } /* - * Returns the drive letter (0 if error) and fills the drive label + * Opens a drive return both the handle and the drive letter */ -char GetDriveInfo(DWORD num, char** label) +static BOOL GetDriveHandle(DWORD num, HANDLE* hDrive, char* DriveLetter) { BOOL r; DWORD size; - HANDLE hDrive; STORAGE_DEVICE_NUMBER sdn = {0}; - static char volume_label[MAX_PATH]; - static char drives[26*2]; + static char drives[26*4]; /* "D:\", "E:\", etc. */ char *drive = drives; char drive_name[] = "\\\\.\\#:"; - *label = "NO_LABEL"; - size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString(0)); - return 0; + return FALSE; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives)); return FALSE; } + *hDrive = INVALID_HANDLE_VALUE; for ( ;*drive; drive += safe_strlen(drive)+1) { if (*drive < 'C') { continue; } safe_sprintf(drive_name, sizeof(drive_name), "\\\\.\\%c:", drive[0]); - hDrive = CreateFileA(drive_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + *hDrive = CreateFileA(drive_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Could not open drive %c: %s\n", WindowsErrorString(0)); continue; } - r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, + r = DeviceIoControl(*hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &size, NULL); if ((!r) || (size <= 0)) { - uprintf("IOCTL_STORAGE_GET_DEVICE_NUMBER failed: %s\n", WindowsErrorString(0)); - CloseHandle(hDrive); - return 0; + uprintf("IOCTL_STORAGE_GET_DEVICE_NUMBER 1 failed: %s\n", WindowsErrorString(0)); + safe_closehandle(*hDrive); + break; } if (sdn.DeviceNumber == num) break; - CloseHandle(hDrive); } - if (*drive && GetVolumeInformationA(drive, volume_label, sizeof(volume_label), NULL, NULL, NULL, NULL, 0)) { - *label = volume_label; + if (DriveLetter != NULL) { + *DriveLetter = *drive; } - return *drive; + return (*hDrive != INVALID_HANDLE_VALUE); +} + +/* + * Returns the drive letter and volume label + */ +static BOOL GetDriveLabel(DWORD num, char* letter, char** label) +{ + HANDLE hDrive; + char DrivePath[] = "#:\\"; + char volume_label[MAX_PATH]; + + *label = "NO_LABEL"; + + if (!GetDriveHandle(num, &hDrive, DrivePath)) + return FALSE; + safe_closehandle(hDrive); + + if (!GetVolumeInformationA(DrivePath, volume_label, sizeof(volume_label), NULL, NULL, NULL, NULL, 0)) { + uprintf("GetVolumeInformation failed: %s\n", WindowsErrorString(0)); + return FALSE; + } + *label = volume_label; + *letter = DrivePath[0]; + + return TRUE; +} + +/* + * Returns the drive letter and volume label + */ +static BOOL GetDriveInfo(DWORD num, LONGLONG* DriveSize) +{ + BOOL r; + HANDLE hDrive; + DWORD size; + BYTE geometry[128]; + + *DriveSize = 0; + + if (!GetDriveHandle(num, &hDrive, NULL)) + return FALSE; + + r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, + NULL, 0, geometry, sizeof(geometry), &size, NULL ); + if (!r || size <= 0) { + uprintf("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX failed: %s\n", WindowsErrorString(0)); + safe_closehandle(hDrive); + return FALSE; + } + *DriveSize = ((PDISK_GEOMETRY_EX)geometry)->DiskSize.QuadPart; + + safe_closehandle(hDrive); + + return TRUE; +} + +static BOOL PopulateProperties(int index) +{ + double HumanReadableSize; + LONGLONG DiskSize; + DWORD DeviceNumber; + char capacity[64]; + char* suffix[] = { "KB", "MB", "GB", "TB", "PB"}; + int i; + + DeviceNumber = (DWORD)ComboBox_GetItemData(hDeviceList, index); + if (!GetDriveInfo(DeviceNumber, &DiskSize)) + return FALSE; + + HumanReadableSize = (double)DiskSize; + for (i=0; iDiskSize.QuadPart / 1024 / 1024; - - drive_letter = GetDriveInfo(storage_device.DeviceNumber, &label); - if (drive_letter) { - safe_sprintf(entry, sizeof(entry), "%s (%I64i MB) (%c:)\n", label, disk_size, drive_letter); - IGNORE_RETVAL(ComboBox_AddStringU(hDeviceList, entry)); + if (GetDriveLabel(device_number.DeviceNumber, &drive_letter, &label)) { + safe_sprintf(entry, sizeof(entry), "%s (%c:)\n", label, drive_letter); + IGNORE_RETVAL(ComboBox_SetItemData(hDeviceList, ComboBox_AddStringU(hDeviceList, entry), device_number.DeviceNumber)); } } } IGNORE_RETVAL(ComboBox_SetCurSel(hDeviceList, 0)); + PopulateProperties(0); return TRUE; } @@ -277,6 +347,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA case WM_INITDIALOG: hDeviceList = GetDlgItem(hDlg, IDC_DEVICE); + hCapacity = GetDlgItem(hDlg, IDC_CAPACITY); GetUSBDevices(); return (INT_PTR)TRUE; diff --git a/usbdos.h b/usbdos.h index 9483da6d..93afae0b 100644 --- a/usbdos.h +++ b/usbdos.h @@ -22,6 +22,9 @@ #define APP_VERSION "USBDOS v0.1.0.1" #define IGNORE_RETVAL(expr) do { (void)(expr); } while(0) +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif #define safe_free(p) do {free((void*)p); p = NULL;} while(0) #define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)