Merge branch 'master' into localization

This commit is contained in:
Pete Batard 2013-07-15 23:11:39 +01:00
commit a976772df6
8 changed files with 159 additions and 99 deletions

View File

@ -1,3 +1,12 @@
o Version 1.3.4 (2013.07.15)
Syslinux v5 support (NEW)
UDF formatting support (NEW - Vista and later only)
More drive handling improvements, to avoid "Could not open media" errors
Fixed support for ISOs with files larger than 4GB files
Fixed elevation request for unprivileged users
Fixed download of c32 files into the application directory
Better compression algorithm for the executable
Other bug fixes and improvements (spelling, UI, etc.)
o Version 1.3.3 (2013.06.10)
Drive handling and hotplug detection overhaul
Add support for raw/unpartitioned drives

View File

@ -413,6 +413,14 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
char tmp[256];
DWORD i, nb_partitions = 0;
// Populate the filesystem data
FileSystemName[0] = 0;
volume_name = GetLogicalName(DriveIndex, TRUE, FALSE);
if ((volume_name == NULL) || (!GetVolumeInformationA(volume_name, NULL, 0, NULL, NULL, NULL, FileSystemName, FileSystemNameSize))) {
uprintf("No volume information for disk 0x%02x\n", DriveIndex);
}
safe_free(volume_name);
hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE);
if (hPhysical == INVALID_HANDLE_VALUE)
return FALSE;
@ -453,7 +461,8 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
uprintf("Partition %d:\n", DriveLayout->PartitionEntry[i].PartitionNumber);
part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType;
uprintf(" Type: %s (0x%02x)\r\n Size: %s (%lld bytes)\r\n Start Sector: %d, Boot: %s, Recognized: %s\n",
GetPartitionType(part_type), part_type, SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength),
((part_type==0x07)&&(FileSystemName[0]!=0))?FileSystemName:GetPartitionType(part_type), part_type,
SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength),
DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors,
DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No");
@ -487,17 +496,34 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
}
safe_closehandle(hPhysical);
// Populate the filesystem data
volume_name = GetLogicalName(DriveIndex, TRUE, FALSE);
if ((volume_name == NULL) || (!GetVolumeInformationA(volume_name, NULL, 0, NULL, NULL, NULL, FileSystemName, FileSystemNameSize))) {
uprintf("No volume information for disk 0x%02x\n", DriveIndex);
FileSystemName[0] = 0;
}
safe_free(volume_name);
return TRUE;
}
/*
* Flush file data
*/
static BOOL FlushDrive(char drive_letter)
{
HANDLE hDrive = INVALID_HANDLE_VALUE;
BOOL r = FALSE;
char logical_drive[] = "\\\\.\\#:";
logical_drive[4] = drive_letter;
hDrive = CreateFileA(logical_drive, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, 0);
if (hDrive == INVALID_HANDLE_VALUE) {
uprintf("Failed to open %c: for flushing: %s\n", drive_letter, WindowsErrorString());
goto out;
}
r = FlushFileBuffers(hDrive);
if (r == FALSE)
uprintf("Failed to flush %c: %s\n", drive_letter, WindowsErrorString());
out:
safe_closehandle(hDrive);
return r;
}
/*
* Unmount of volume using the DISMOUNT_VOLUME ioctl
*/
@ -512,6 +538,63 @@ BOOL UnmountVolume(HANDLE hDrive)
return TRUE;
}
/*
* Mount the volume identified by drive_guid to mountpoint drive_name
*/
BOOL MountVolume(char* drive_name, char *drive_guid)
{
char mounted_guid[52]; // You need at least 51 characters on XP
if (!SetVolumeMountPointA(drive_name, drive_guid)) {
// If the OS was faster than us at remounting the drive, this operation can fail
// with ERROR_DIR_NOT_EMPTY. If that's the case, just check that mountpoints match
if (GetLastError() == ERROR_DIR_NOT_EMPTY) {
if (!GetVolumeNameForVolumeMountPointA(drive_name, mounted_guid, sizeof(mounted_guid))) {
uprintf("%s already mounted, but volume GUID could not be checked: %s\n",
drive_name, WindowsErrorString());
return FALSE;
}
if (safe_strcmp(drive_guid, mounted_guid) != 0) {
uprintf("%s already mounted, but volume GUID doesn't match:\r\n expected %s, got %s\n",
drive_name, drive_guid, mounted_guid);
return FALSE;
}
uprintf("%s was already mounted as %s\n", drive_guid, drive_name);
} else {
return FALSE;
}
}
return TRUE;
}
/*
* Issue a complete remount of the volume
*/
BOOL RemountVolume(char* drive_name)
{
char drive_guid[51];
// UDF requires a sync/flush, and it's also a good idea for other FS's
FlushDrive(drive_name[0]);
if (GetVolumeNameForVolumeMountPointA(drive_name, drive_guid, sizeof(drive_guid))) {
if (DeleteVolumeMountPointA(drive_name)) {
Sleep(200);
if (MountVolume(drive_name, drive_guid)) {
uprintf("Successfully remounted %s on %s\n", &drive_guid[4], drive_name);
} else {
uprintf("Failed to remount %s on %s\n", &drive_guid[4], drive_name);
// This will leave the drive inaccessible and must be flagged as an error
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_REMOUNT_VOLUME);
return FALSE;
}
} else {
uprintf("Could not remount %s %s\n", drive_name, WindowsErrorString());
// Try to continue regardless
}
}
return TRUE;
}
/* MinGW is unhappy about accessing partitions beside the first unless we redef */
typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
DWORD PartitionStyle;
@ -552,6 +635,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart =
SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack;
}
// TODO: should we try to align the following to the cluster size as well?
size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector;
switch (partition_style) {
@ -617,6 +701,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
break;
case FS_NTFS:
case FS_EXFAT:
case FS_UDF:
DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x07; // NTFS
break;
case FS_FAT32:

View File

@ -51,8 +51,7 @@ DWORD FormatStatus;
badblocks_report report;
static float format_percent = 0.0f;
static int task_number = 0;
/* Number of steps for each FS for FCC_STRUCTURE_PROGRESS */
const int nb_steps[FS_MAX] = { 5, 5, 12, 10 };
extern const int nb_steps[FS_MAX];
static int fs_index = 0;
BOOL force_large_fat32 = FALSE;
@ -607,13 +606,13 @@ static BOOL FormatDrive(DWORD DriveIndex)
{
BOOL r = FALSE;
PF_DECL(FormatEx);
char* VolumeName = NULL;
WCHAR* wVolumeName = NULL;
char FSType[32], format_status[64];
char *locale, *VolumeName = NULL;
WCHAR* wVolumeName = NULL;
WCHAR wFSType[32];
WCHAR wLabel[64];
ULONG ulClusterSize;
size_t i;
char* locale;
GetWindowTextA(hFileSystem, FSType, ARRAYSIZE(FSType));
safe_sprintf(format_status, ARRAYSIZE(format_status), "Formatting (%s)...", FSType);
@ -643,13 +642,19 @@ static BOOL FormatDrive(DWORD DriveIndex)
GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel));
// Make sure the label is valid
ToValidLabel(wLabel, (wFSType[0] == 'F') && (wFSType[1] == 'A') && (wFSType[2] == 'T'));
uprintf("Using cluster size: %d bytes\n", ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize)));
ulClusterSize = (ULONG)ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize));
if (ulClusterSize < 0x200) {
// 0 is FormatEx's value for default, which we need to use for UDF
ulClusterSize = 0;
uprintf("Using default cluster size\n");
} else {
uprintf("Using cluster size: %d bytes\n", ulClusterSize);
}
format_percent = 0.0f;
task_number = 0;
fs_index = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
pfFormatEx(wVolumeName, SelectedDrive.Geometry.MediaType, wFSType, wLabel,
IsChecked(IDC_QUICKFORMAT), (ULONG)ComboBox_GetItemData(hClusterSize, ComboBox_GetCurSel(hClusterSize)),
FormatExCallback);
IsChecked(IDC_QUICKFORMAT), ulClusterSize, FormatExCallback);
if (!IS_ERROR(FormatStatus)) {
uprintf("Format completed.\n");
r = TRUE;
@ -1092,61 +1097,6 @@ out:
return r;
}
/*
* Mount the volume identified by drive_guid to mountpoint drive_name
*/
static BOOL MountVolume(char* drive_name, char *drive_guid)
{
char mounted_guid[52]; // You need at least 51 characters on XP
if (!SetVolumeMountPointA(drive_name, drive_guid)) {
// If the OS was faster than us at remounting the drive, this operation can fail
// with ERROR_DIR_NOT_EMPTY. If that's the case, just check that mountpoints match
if (GetLastError() == ERROR_DIR_NOT_EMPTY) {
if (!GetVolumeNameForVolumeMountPointA(drive_name, mounted_guid, sizeof(mounted_guid))) {
uprintf("%s already mounted, but volume GUID could not be checked: %s\n",
drive_name, WindowsErrorString());
return FALSE;
}
if (safe_strcmp(drive_guid, mounted_guid) != 0) {
uprintf("%s already mounted, but volume GUID doesn't match:\r\n expected %s, got %s\n",
drive_name, drive_guid, mounted_guid);
return FALSE;
}
uprintf("%s was already mounted as %s\n", drive_guid, drive_name);
} else {
return FALSE;
}
}
return TRUE;
}
/*
* Issue a complete remount of the volume
*/
static BOOL RemountVolume(char* drive_name)
{
char drive_guid[51];
if (GetVolumeNameForVolumeMountPointA(drive_name, drive_guid, sizeof(drive_guid))) {
if (DeleteVolumeMountPointA(drive_name)) {
Sleep(200);
if (MountVolume(drive_name, drive_guid)) {
uprintf("Successfully remounted %s on %s\n", &drive_guid[4], drive_name);
} else {
uprintf("Failed to remount %s on %s\n", &drive_guid[4], drive_name);
// This will leave the drive inaccessible and must be flagged as an error
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_REMOUNT_VOLUME);
return FALSE;
}
} else {
uprintf("Could not remount %s %s\n", drive_name, WindowsErrorString());
// Try to continue regardless
}
}
return TRUE;
}
/*
* Detect if a Windows Format prompt is active, by enumerating the
* whole Windows tree and looking for the relevant popup

View File

@ -303,7 +303,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
goto out;
}
if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)) {
if (!HttpSendRequestA(hRequest, NULL, 0, NULL, 0)) {
uprintf("Unable to send request: %s\n", WinInetErrorString());
goto out;
}
@ -409,6 +409,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
int i, j, k, verbose = 0, verpos[4];
static const char* archname[] = {"win_x86", "win_x64"};
static const char* channel[] = {"release", "beta"}; // release channel
const char* accept_types[] = {"*/*\0", NULL};
DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus;
char* buf = NULL;
char agent[64], hostname[64], urlpath[128], mime[32];
@ -514,10 +515,10 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
UrlParts.dwUrlPathLength = sizeof(urlpath);
for (i=0; i<ARRAYSIZE(verpos); i++) {
vvuprintf("Trying %s\n", UrlParts.lpszUrlPath);
hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, (const char**)"*/*\0",
hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, accept_types,
INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES|
INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL);
if ((hRequest == NULL) || (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)))
if ((hRequest == NULL) || (!HttpSendRequestA(hRequest, NULL, 0, NULL, 0)))
goto out;
// Ensure that we get a text file

View File

@ -86,9 +86,12 @@ struct {
UINT uAlign;
} bi_iso = {0}, bi_up = {0}, bi_down = {0}; // BUTTON_IMAGELIST
static const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "exFAT" };
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 };
// Don't ask me - just following the MS "standard" here
static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes","4096 bytes","8192 bytes",
// We hijack 256 as a "Default" for UDF, since we can't set clustersize there
static const char* ClusterSizeLabel[] = { "Default", "512 bytes", "1024 bytes","2048 bytes","4096 bytes","8192 bytes",
"16 kilobytes", "32 kilobytes", "64 kilobytes", "128 kilobytes", "256 kilobytes", "512 kilobytes",
"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" };
static const char* BiosTypeLabel[BT_MAX] = { "BIOS", "UEFI" };
@ -242,8 +245,8 @@ static BOOL DefineClusterSizes(void)
}
}
// NTFS
if (SelectedDrive.DiskSize < 256*TB) {
// NTFS
SelectedDrive.ClusterSize[FS_NTFS].Allowed = 0x0001FE00;
for (i=16; i<=256; i<<=1) { // 7 MB -> 256 TB
if (SelectedDrive.DiskSize < i*TB) {
@ -251,17 +254,23 @@ static BOOL DefineClusterSizes(void)
break;
}
}
}
// exFAT
if (SelectedDrive.DiskSize < 256*TB) {
SelectedDrive.ClusterSize[FS_EXFAT].Allowed = 0x03FFFE00;
if (SelectedDrive.DiskSize < 256*MB) // < 256 MB
SelectedDrive.ClusterSize[FS_EXFAT].Default = 4*1024;
else if (SelectedDrive.DiskSize < 32*GB) // < 32 GB
SelectedDrive.ClusterSize[FS_EXFAT].Default = 32*1024;
else
SelectedDrive.ClusterSize[FS_EXFAT].Default = 28*1024;
// exFAT (requires KB955704 installed on XP => don't bother)
if (nWindowsVersion > WINDOWS_XP) {
SelectedDrive.ClusterSize[FS_EXFAT].Allowed = 0x03FFFE00;
if (SelectedDrive.DiskSize < 256*MB) // < 256 MB
SelectedDrive.ClusterSize[FS_EXFAT].Default = 4*1024;
else if (SelectedDrive.DiskSize < 32*GB) // < 32 GB
SelectedDrive.ClusterSize[FS_EXFAT].Default = 32*1024;
else
SelectedDrive.ClusterSize[FS_EXFAT].Default = 28*1024;
}
// UDF (only supported for Vista and later)
if (nWindowsVersion >= WINDOWS_VISTA) {
SelectedDrive.ClusterSize[FS_UDF].Allowed = 0x00000100;
SelectedDrive.ClusterSize[FS_UDF].Default = 1;
}
}
out:
@ -311,7 +320,7 @@ static BOOL SetClusterSizes(int FSType)
return FALSE;
}
for(i=0,j=0x200,k=0;j<0x10000000;i++,j<<=1) {
for(i=0,j=0x100,k=0;j<0x10000000;i++,j<<=1) {
if (j & SelectedDrive.ClusterSize[FSType].Allowed) {
safe_sprintf(szClustSize, sizeof(szClustSize), "%s", ClusterSizeLabel[i]);
if (j == SelectedDrive.ClusterSize[FSType].Default) {
@ -1452,7 +1461,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
int nDeviceIndex, fs, bt, i, nWidth, nHeight;
static DWORD DeviceNum = 0, LastRefresh = 0;
char tmp[128], str[MAX_PATH];
static UINT uDOSChecked = BST_CHECKED, uQFChecked;
static UINT uBootChecked = BST_CHECKED, uQFChecked;
static BOOL first_log_display = TRUE, user_changed_label = FALSE;
switch (message) {
@ -1648,13 +1657,16 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
}
break;
}
if (fs == FS_EXFAT) {
if ((fs == FS_EXFAT) || (fs == FS_UDF)) {
if (IsWindowEnabled(hBoot)) {
// unlikely to be supported by BIOSes => don't bother
IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, 0));
uDOSChecked = IsDlgButtonChecked(hMainDialog, IDC_BOOT);
uBootChecked = IsDlgButtonChecked(hMainDialog, IDC_BOOT);
CheckDlgButton(hDlg, IDC_BOOT, BST_UNCHECKED);
EnableBootOptions(FALSE);
} else if (IsDlgButtonChecked(hMainDialog, IDC_BOOT)) {
uBootChecked = TRUE;
CheckDlgButton(hDlg, IDC_BOOT, BST_UNCHECKED);
}
SetMBRProps();
break;
@ -1687,7 +1699,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
EnableWindow(hBoot, TRUE);
EnableWindow(hBootType, TRUE);
EnableWindow(hSelectISO, TRUE);
CheckDlgButton(hDlg, IDC_BOOT, uDOSChecked);
CheckDlgButton(hDlg, IDC_BOOT, uBootChecked);
}
SetMBRProps();
break;

View File

@ -153,6 +153,7 @@ enum {
FS_FAT16 = 0,
FS_FAT32,
FS_NTFS,
FS_UDF,
FS_EXFAT,
FS_MAX
};
@ -316,7 +317,9 @@ 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 MountVolume(char* drive_name, char *drive_guid);
extern BOOL UnmountVolume(HANDLE hDrive);
extern BOOL RemountVolume(char* drive_name);
extern BOOL CreateProgress(void);
extern BOOL SetAutorun(const char* path);
extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc);

View File

@ -30,7 +30,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.3.4.267"
CAPTION "Rufus v1.3.4.270"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,291,50,14
@ -277,8 +277,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,3,4,267
PRODUCTVERSION 1,3,4,267
FILEVERSION 1,3,4,270
PRODUCTVERSION 1,3,4,270
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -295,13 +295,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.3.4.267"
VALUE "FileVersion", "1.3.4.270"
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.3.4.267"
VALUE "ProductVersion", "1.3.4.270"
END
END
BLOCK "VarFileInfo"

View File

@ -41,7 +41,7 @@ SysType msdos_systypes[] = {
{ 0x04, N_("Small FAT16") },
{ 0x05, N_("Extended") },
{ 0x06, N_("FAT16") },
{ 0x07, N_("NTFS") },
{ 0x07, N_("NTFS/exFAT/UDF") },
{ 0x08, N_("AIX") },
{ 0x09, N_("AIX Bootable") },
{ 0x0a, N_("OS/2 Boot Manager") },