1
1
Fork 0
mirror of https://github.com/pbatard/rufus.git synced 2024-08-14 23:57:05 +00:00

[ui] add experimental optional display of transfer speed and time remaining

* You can use <Alt> to switch modes during an operation that supports it (e.g. Checksum
  computation, DD image writing or zeroing, save to VHD, download, etc.
* IMPORTANT: This is *NOT* available for all operations. Especially, if you were hoping
  to get transfer speed or ETA during ISO or WIM extraction, you *WILL* be disappointed.
* Also harmonize the code in checksum.c
This commit is contained in:
Pete Batard 2019-08-20 18:06:07 +01:00
parent 94e2015edf
commit af95de8198
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
16 changed files with 525 additions and 430 deletions

View file

@ -2,8 +2,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 3.5\n" "Project-Id-Version: 3.5\n"
"Report-Msgid-Bugs-To: pete@akeo.ie\n" "Report-Msgid-Bugs-To: pete@akeo.ie\n"
"POT-Creation-Date: 2019-03-12 13:52+0000\n" "POT-Creation-Date: 2019-08-20 17:03+0100\n"
"PO-Revision-Date: 2019-04-11 14:19+0100\n" "PO-Revision-Date: 2019-08-20 17:03+0100\n"
"Language: fr_FR\n" "Language: fr_FR\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -13,7 +13,7 @@ msgstr ""
"X-Rufus-LCID: 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c\n" "X-Rufus-LCID: 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"X-Generator: Poedit 2.2.1\n" "X-Generator: Poedit 2.2.3\n"
#. • IDD_DIALOG → IDS_DRIVE_PROPERTIES_TXT #. • IDD_DIALOG → IDS_DRIVE_PROPERTIES_TXT
msgid "Drive Properties" msgid "Drive Properties"
@ -1285,8 +1285,8 @@ msgstr "%s sauvegardé"
#. • MSG_217 #. • MSG_217
#. #.
#. Formatting status (make sure you use a double % to print the percent sign) #. Formatting status (make sure you use a double % to print the percent sign)
msgid "Formatting: %0.1f%% completed" msgid "Formatting: %s"
msgstr "Formatage : %0.1f%% complété" msgstr "Formatage : %s"
#. • MSG_218 #. • MSG_218
msgid "Creating file system: Task %d/%d completed" msgid "Creating file system: Task %d/%d completed"
@ -1335,11 +1335,11 @@ msgid "Closing existing volume..."
msgstr "Fermeture des volumes existants..." msgstr "Fermeture des volumes existants..."
#. • MSG_228 #. • MSG_228
msgid "Writing master boot record..." msgid "Writing Master Boot Record..."
msgstr "Ecriture du MBR..." msgstr "Ecriture du MBR..."
#. • MSG_229 #. • MSG_229
msgid "Writing partition boot record..." msgid "Writing Partition Boot Record..."
msgstr "Ecriture du PBR..." msgstr "Ecriture du PBR..."
#. • MSG_230 #. • MSG_230
@ -1347,8 +1347,8 @@ msgid "Copying DOS files..."
msgstr "Copie des fichiers DOS..." msgstr "Copie des fichiers DOS..."
#. • MSG_231 #. • MSG_231
msgid "Copying ISO files..." msgid "Copying ISO files: %s"
msgstr "Copie des fichiers ISO..." msgstr "Copie des fichiers ISO : %s"
#. • MSG_232 #. • MSG_232
msgid "Win7 EFI boot setup (This may take a while)..." msgid "Win7 EFI boot setup (This may take a while)..."
@ -1403,8 +1403,8 @@ msgstr ""
"Le téléchargement va être supprimé. Veuillez consulter le log pour plus de détails." "Le téléchargement va être supprimé. Veuillez consulter le log pour plus de détails."
#. • MSG_241 #. • MSG_241
msgid "Downloading: %0.1f%%" msgid "Downloading: %s"
msgstr "Téléchargement : %0.1f%%" msgstr "Téléchargement : %s"
#. • MSG_242 #. • MSG_242
msgid "Failed to download file." msgid "Failed to download file."
@ -1485,8 +1485,8 @@ msgid "NTFS compression"
msgstr "Compression NTFS" msgstr "Compression NTFS"
#. • MSG_261 #. • MSG_261
msgid "Writing image: %0.1f%% completed" msgid "Writing image: %s"
msgstr "Ecriture d'image : %0.1f%% complété" msgstr "Ecriture d'image : %s"
#. • MSG_262 #. • MSG_262
#. #.
@ -1513,8 +1513,8 @@ msgid "Dual UEFI/BIOS mode"
msgstr "Mode dual UEFI/BIOS" msgstr "Mode dual UEFI/BIOS"
#. • MSG_267 #. • MSG_267
msgid "Applying Windows image: %0.1f%% completed" msgid "Applying Windows image: %s"
msgstr "Application de l'image Windows : %0.1f%% complété" msgstr "Application de l'image Windows : %s"
#. • MSG_268 #. • MSG_268
msgid "Applying Windows image..." msgid "Applying Windows image..."
@ -1529,8 +1529,8 @@ msgid "USB debug"
msgstr "Debug USB" msgstr "Debug USB"
#. • MSG_271 #. • MSG_271
msgid "Computing image checksums: %0.1f%% completed" msgid "Computing image checksums: %s"
msgstr "Calculation des checksums de l'image : %0.1f%% complété" msgstr "Calculation des checksums de l'image : %s"
#. • MSG_272 #. • MSG_272
msgid "Compute the MD5, SHA1 and SHA256 checksums for the selected image" msgid "Compute the MD5, SHA1 and SHA256 checksums for the selected image"
@ -1607,12 +1607,12 @@ msgid ""
"Are you sure you want to run this file?" "Are you sure you want to run this file?"
msgstr "" msgstr ""
"L'exécutable téléchargé est signé par '%s'.\n" "L'exécutable téléchargé est signé par '%s'.\n"
"Ce nest pas une signature que nous reconnaissons et pourrait indiquer une activité malicieuse...\n" "Il ne s'agit pas d'une signature que nous connaissons et peut indiquer une activité malicieuse...\n"
"Êtes-vous certain de vouloir lancer ce fichier ?" "Êtes-vous certain de vouloir lancer ce fichier ?"
#. • MSG_286 #. • MSG_286
msgid "Zeroing drive: %0.1f%% completed" msgid "Zeroing drive: %s"
msgstr "Effacement à zéro : %0.1f%% complété" msgstr "Effacement à zéro : %s"
#. • MSG_287 #. • MSG_287
msgid "Detection of non-USB removable drives" msgid "Detection of non-USB removable drives"
@ -1716,5 +1716,5 @@ msgstr "Utilisez cette option pour indiquer si vous voulez utiliser ce périphé
#. #.
#. You can see this status message by pressing <Ctrl>-<Alt>-<Z> and then selecting START. #. You can see this status message by pressing <Ctrl>-<Alt>-<Z> and then selecting START.
#. It's the same as MSG_286 but with a process that *may* be faster, hence the name. #. It's the same as MSG_286 but with a process that *may* be faster, hence the name.
msgid "Fast-zeroing drive: %0.1f%% completed" msgid "Fast-zeroing drive: %s"
msgstr "Effacement 'rapide' à zéro : %0.1f%% complété" msgstr "Effacement 'rapide' à zéro : %s"

File diff suppressed because it is too large Load diff

View file

@ -91,7 +91,7 @@ static const uint32_t K[64] = {
}; };
/* /*
* For convenience, we use a common context for all the checksums algorithms, * For convenience, we use a common context for all the checksum algorithms,
* which means some elements may be unused... * which means some elements may be unused...
*/ */
typedef struct ALIGNED(64) { typedef struct ALIGNED(64) {
@ -159,10 +159,10 @@ static void sha1_transform(SUM_CONTEXT *ctx, const unsigned char *data)
} }
#endif #endif
#define K1 0x5A827999L #define K1 0x5a827999L
#define K2 0x6ED9EBA1L #define K2 0x6ed9eba1L
#define K3 0x8F1BBCDCL #define K3 0x8f1bbcdcL
#define K4 0xCA62C1D6L #define K4 0xca62c1d6L
#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) #define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
#define F2(x,y,z) ( x ^ y ^ z ) #define F2(x,y,z) ( x ^ y ^ z )
#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) #define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
@ -880,9 +880,8 @@ DWORD WINAPI SumThread(void* param)
DWORD_PTR* thread_affinity = (DWORD_PTR*)param; DWORD_PTR* thread_affinity = (DWORD_PTR*)param;
HANDLE sum_thread[CHECKSUM_MAX] = { NULL, NULL, NULL }; HANDLE sum_thread[CHECKSUM_MAX] = { NULL, NULL, NULL };
HANDLE h = INVALID_HANDLE_VALUE; HANDLE h = INVALID_HANDLE_VALUE;
uint64_t rb, LastRefresh = 0; uint64_t rb;
int i, _bufnum, r = -1; int i, _bufnum, r = -1;
float format_percent = 0.0f;
if ((image_path == NULL) || (thread_affinity == NULL)) if ((image_path == NULL) || (thread_affinity == NULL))
ExitThread(r); ExitThread(r);
@ -926,15 +925,10 @@ DWORD WINAPI SumThread(void* param)
bufnum = 0; bufnum = 0;
_bufnum = 0; _bufnum = 0;
read_size[0] = 1; // Don't trigger the first loop break read_size[0] = 1; // Don't trigger the first loop break
UpdateProgressWithInfoInit(hMainDialog, FALSE);
for (rb = 0; ;rb += read_size[_bufnum]) { for (rb = 0; ;rb += read_size[_bufnum]) {
// Update the progress and check for cancel // Update the progress and check for cancel
if (GetTickCount64() > LastRefresh + MAX_REFRESH) { UpdateProgressWithInfo(OP_NOOP_WITH_TASKBAR, MSG_271, rb, img_report.image_size);
LastRefresh = GetTickCount64();
format_percent = (100.0f*rb) / (1.0f*img_report.image_size);
PrintInfo(0, MSG_271, format_percent);
SendMessage(hProgress, PBM_SETPOS, (WPARAM)((format_percent / 100.0f)*MAX_PROGRESS), 0);
SetTaskbarProgressValue(rb, img_report.image_size);
}
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
// Signal the threads that we have data to process // Signal the threads that we have data to process

View file

@ -334,7 +334,7 @@ static BOOL ExtractMSDOS(const char* path)
if (memcmp(extractlist[j], &DiskImage[FAT12_ROOTDIR_OFFSET + i*FAT_BYTES_PER_DIRENT], 8+3) == 0) { if (memcmp(extractlist[j], &DiskImage[FAT12_ROOTDIR_OFFSET + i*FAT_BYTES_PER_DIRENT], 8+3) == 0) {
r = ExtractFAT(i, (j<3)?path:locale_path); r = ExtractFAT(i, (j<3)?path:locale_path);
if ((j == 2) || (j == 7) || (j == 12)) if ((j == 2) || (j == 7) || (j == 12))
UpdateProgress(OP_DOS, -1.0f); UpdateProgress(OP_FILE_COPY, -1.0f);
} }
} }
} }
@ -405,7 +405,7 @@ BOOL ExtractFreeDOS(const char* path)
uprintf("Successfully wrote '%s' (%d bytes)\n", filename, res_size); uprintf("Successfully wrote '%s' (%d bytes)\n", filename, res_size);
if ((i == 4) || (i == 10) || (i == 16) || (i == 22) || (i == ARRAYSIZE(res_name)-1)) if ((i == 4) || (i == 10) || (i == 16) || (i == 22) || (i == ARRAYSIZE(res_name)-1))
UpdateProgress(OP_DOS, -1.0f); UpdateProgress(OP_FILE_COPY, -1.0f);
} }
return SetDOSLocale(path, TRUE); return SetDOSLocale(path, TRUE);

View file

@ -59,7 +59,6 @@
const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT", "ReFS", "ext2", "ext3", "ext4" }; const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT", "ReFS", "ext2", "ext3", "ext4" };
DWORD FormatStatus = 0, LastWriteError = 0; DWORD FormatStatus = 0, LastWriteError = 0;
badblocks_report report = { 0 }; badblocks_report report = { 0 };
static uint64_t LastRefresh = 0;
static float format_percent = 0.0f; static float format_percent = 0.0f;
static int task_number = 0; static int task_number = 0;
extern const int nb_steps[FS_MAX]; extern const int nb_steps[FS_MAX];
@ -416,7 +415,7 @@ static BOOL FormatFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD Cluste
goto out; goto out;
} }
PrintInfoDebug(0, MSG_222, "Large FAT32"); PrintInfoDebug(0, MSG_222, "Large FAT32");
LastRefresh = 0; UpdateProgressWithInfoInit(NULL, TRUE);
VolumeId = GetVolumeID(); VolumeId = GetVolumeID();
// Open the drive and lock it // Open the drive and lock it
@ -616,7 +615,7 @@ static BOOL FormatFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD Cluste
} }
for (i=0; i<(SystemAreaSize+BurstSize-1); i+=BurstSize) { for (i=0; i<(SystemAreaSize+BurstSize-1); i+=BurstSize) {
UPDATE_PERCENT(MSG_217, (100.0f*i) / (1.0f*(SystemAreaSize + BurstSize))); UpdateProgressWithInfo(OP_FORMAT, MSG_217, (uint64_t)i, (uint64_t)(SystemAreaSize + BurstSize));
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
if (write_sectors(hLogicalVolume, BytesPerSect, i, BurstSize, pZeroSect) != (BytesPerSect*BurstSize)) { if (write_sectors(hLogicalVolume, BytesPerSect, i, BurstSize, pZeroSect) != (BytesPerSect*BurstSize)) {
die("Error clearing reserved sectors", ERROR_WRITE_FAULT); die("Error clearing reserved sectors", ERROR_WRITE_FAULT);
@ -803,14 +802,15 @@ const char* error_message(errcode_t error_code)
} }
} }
static float ext2_percent_start = 0.0f, ext2_percent_share = 50.0f; static float ext2_percent_start = 0.0f, ext2_percent_share = 0.5f;
const float ext2_max_marker = 80.0f; const float ext2_max_marker = 80.0f;
errcode_t ext2fs_print_progress(int64_t cur_value, int64_t max_value) errcode_t ext2fs_print_progress(int64_t cur_value, int64_t max_value)
{ {
static int64_t last_value = -1; static int64_t last_value = -1;
if (max_value == 0) if (max_value == 0)
return 0; return 0;
UPDATE_PERCENT(MSG_217, ext2_percent_start + ext2_percent_share * cur_value / (float)max_value); // TODO: Need to use OP_CREATE_FS here for standalone format
UpdateProgressWithInfo(OP_FORMAT, MSG_217, (uint64_t)((ext2_percent_start * max_value) + (ext2_percent_share * cur_value)), max_value);
cur_value = (int64_t)(((float)cur_value / (float)max_value) * min(ext2_max_marker, (float)max_value)); cur_value = (int64_t)(((float)cur_value / (float)max_value) * min(ext2_max_marker, (float)max_value));
if ((cur_value < last_value) || (cur_value > last_value)) { if ((cur_value < last_value) || (cur_value > last_value)) {
last_value = cur_value; last_value = cur_value;
@ -897,7 +897,7 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP
FSName = FileSystemLabel[FS_EXT3]; FSName = FileSystemLabel[FS_EXT3];
PrintInfoDebug(0, MSG_222, FSName); PrintInfoDebug(0, MSG_222, FSName);
LastRefresh = 0; UpdateProgressWithInfoInit(NULL, TRUE);
// Figure out the volume size and block size // Figure out the volume size and block size
r = ext2fs_get_device_size2(volume_name, KB, &size); r = ext2fs_get_device_size2(volume_name, KB, &size);
@ -987,7 +987,7 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP
} }
ext2_percent_start = 0.0f; ext2_percent_start = 0.0f;
ext2_percent_share = (FSName[3] == '2') ? 100.0f : 50.0f; ext2_percent_share = (FSName[3] == '2') ? 1.0f : 0.5f;
uprintf("Creating %d inode sets: [1 marker = %0.1f set(s)]", ext2fs->group_desc_count, uprintf("Creating %d inode sets: [1 marker = %0.1f set(s)]", ext2fs->group_desc_count,
max((float)ext2fs->group_desc_count / ext2_max_marker, 1.0f)); max((float)ext2fs->group_desc_count / ext2_max_marker, 1.0f));
for (i = 0; i < (int)ext2fs->group_desc_count; i++) { for (i = 0; i < (int)ext2fs->group_desc_count; i++) {
@ -1041,7 +1041,7 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP
if (FSName[3] != '2') { if (FSName[3] != '2') {
// Create the journal // Create the journal
ext2_percent_start = 50.0f; ext2_percent_start = 0.5f;
journal_size = ext2fs_default_journal_size(ext2fs_blocks_count(ext2fs->super)); journal_size = ext2fs_default_journal_size(ext2fs_blocks_count(ext2fs->super));
journal_size /= 2; // That journal init is really killing us! journal_size /= 2; // That journal init is really killing us!
uprintf("Creating %d journal blocks: [1 marker = %0.1f block(s)]", journal_size, uprintf("Creating %d journal blocks: [1 marker = %0.1f block(s)]", journal_size,
@ -1092,7 +1092,7 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP
uprintf("Could not create %s volume: %s", FSName, error_message(r)); uprintf("Could not create %s volume: %s", FSName, error_message(r));
goto out; goto out;
} }
UPDATE_PERCENT(MSG_217, 100.0f); UpdateProgressWithInfo(OP_FORMAT, MSG_217, 100, 100);
uprintf("Done"); uprintf("Done");
ret = TRUE; ret = TRUE;
@ -1123,7 +1123,7 @@ static BOOL FormatDriveVds(DWORD DriveIndex, uint64_t PartitionOffset, DWORD Clu
} else { } else {
PrintInfoDebug(0, MSG_222, FSName); PrintInfoDebug(0, MSG_222, FSName);
} }
LastRefresh = 0; UpdateProgressWithInfoInit(NULL, TRUE);
VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE); VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE);
wVolumeName = utf8_to_wchar(VolumeName); wVolumeName = utf8_to_wchar(VolumeName);
if (wVolumeName == NULL) { if (wVolumeName == NULL) {
@ -2197,7 +2197,7 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
AltUnmountVolume(ms_efi, FALSE); AltUnmountVolume(ms_efi, FALSE);
} }
PrintInfo(0, MSG_267, 99.9f); PrintInfo(0, MSG_267, 99.9f);
UpdateProgress(OP_DOS, 99.9f); UpdateProgress(OP_FILE_COPY, 99.9f);
// The following are non fatal if they fail // The following are non fatal if they fail
@ -2233,14 +2233,14 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
if (fd != NULL) if (fd != NULL)
fclose(fd); fclose(fd);
PrintInfo(0, MSG_267, 100.0f); PrintInfo(0, MSG_267, 100.0f);
UpdateProgress(OP_DOS, 100.0f); UpdateProgress(OP_FILE_COPY, 100.0f);
return TRUE; return TRUE;
} }
static void update_progress(const uint64_t processed_bytes) static void update_progress(const uint64_t processed_bytes)
{ {
UPDATE_PERCENT(MSG_261, (100.0f*processed_bytes) / (1.0f*img_report.image_size)); UpdateProgressWithInfo(OP_FORMAT, MSG_261, processed_bytes, img_report.image_size);
} }
/* Write an image file or zero a drive */ /* Write an image file or zero a drive */
@ -2259,7 +2259,7 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
li.QuadPart = 0; li.QuadPart = 0;
if (!SetFilePointerEx(hPhysicalDrive, li, NULL, FILE_BEGIN)) if (!SetFilePointerEx(hPhysicalDrive, li, NULL, FILE_BEGIN))
uprintf("Warning: Unable to rewind image position - wrong data might be copied!"); uprintf("Warning: Unable to rewind image position - wrong data might be copied!");
LastRefresh = 0; UpdateProgressWithInfoInit(NULL, FALSE);
if (img_report.compression_type != BLED_COMPRESSION_NONE) { if (img_report.compression_type != BLED_COMPRESSION_NONE) {
uprintf("Writing compressed image..."); uprintf("Writing compressed image...");
@ -2300,7 +2300,7 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
// will be as fast, if not faster, than whatever async scheme you can come up with. // will be as fast, if not faster, than whatever async scheme you can come up with.
rSize = BufSize; rSize = BufSize;
for (wb = 0, wSize = 0; wb < (uint64_t)SelectedDrive.DiskSize; wb += wSize) { for (wb = 0, wSize = 0; wb < (uint64_t)SelectedDrive.DiskSize; wb += wSize) {
UPDATE_PERCENT(hSourceImage?MSG_261:fast_zeroing?MSG_306:MSG_286, (100.0f*wb)/(1.0f*target_size)); UpdateProgressWithInfo(OP_FORMAT, hSourceImage ? MSG_261 : fast_zeroing ? MSG_306 : MSG_286, wb, target_size);
if (hSourceImage != NULL) { if (hSourceImage != NULL) {
s = ReadFile(hSourceImage, buffer, BufSize, &rSize, NULL); s = ReadFile(hSourceImage, buffer, BufSize, &rSize, NULL);
if (!s) { if (!s) {
@ -2834,7 +2834,7 @@ DWORD WINAPI FormatThread(void* param)
if (boot_type != BT_NON_BOOTABLE) { if (boot_type != BT_NON_BOOTABLE) {
if ((boot_type == BT_MSDOS) || (boot_type == BT_FREEDOS)) { if ((boot_type == BT_MSDOS) || (boot_type == BT_FREEDOS)) {
UpdateProgress(OP_DOS, -1.0f); UpdateProgress(OP_FILE_COPY, -1.0f);
PrintInfoDebug(0, MSG_230); PrintInfoDebug(0, MSG_230);
if (!ExtractDOS(drive_name)) { if (!ExtractDOS(drive_name)) {
if (!IS_ERROR(FormatStatus)) if (!IS_ERROR(FormatStatus))
@ -2849,7 +2849,7 @@ DWORD WINAPI FormatThread(void* param)
if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE)) if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE))
uprintf("Failed to copy file: %s", WindowsErrorString()); uprintf("Failed to copy file: %s", WindowsErrorString());
} else if ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso)) { } else if ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso)) {
UpdateProgress(OP_DOS, 0.0f); UpdateProgress(OP_FILE_COPY, 0.0f);
drive_name[2] = 0; // Ensure our drive is something like 'D:' drive_name[2] = 0; // Ensure our drive is something like 'D:'
if (windows_to_go) { if (windows_to_go) {
PrintInfoDebug(0, MSG_268); PrintInfoDebug(0, MSG_268);
@ -2859,7 +2859,6 @@ DWORD WINAPI FormatThread(void* param)
goto out; goto out;
} }
} else { } else {
PrintInfoDebug(0, MSG_231);
if (!ExtractISO(image_path, drive_name, FALSE)) { if (!ExtractISO(image_path, drive_name, FALSE)) {
if (!IS_ERROR(FormatStatus)) if (!IS_ERROR(FormatStatus))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
@ -2948,7 +2947,6 @@ DWORD WINAPI SaveImageThread(void* param)
int i; int i;
PrintInfoDebug(0, MSG_225); PrintInfoDebug(0, MSG_225);
LastRefresh = 0;
switch (img_save->Type) { switch (img_save->Type) {
case IMG_SAVE_TYPE_VHD: case IMG_SAVE_TYPE_VHD:
hPhysicalDrive = GetPhysicalHandle(img_save->DeviceNum, TRUE, FALSE, FALSE); hPhysicalDrive = GetPhysicalHandle(img_save->DeviceNum, TRUE, FALSE, FALSE);
@ -2991,6 +2989,7 @@ DWORD WINAPI SaveImageThread(void* param)
// Don't bother trying for something clever, using double buffering overlapped and whatnot: // Don't bother trying for something clever, using double buffering overlapped and whatnot:
// With Windows' default optimizations, sync read + sync write for sequential operations // With Windows' default optimizations, sync read + sync write for sequential operations
// will be as fast, if not faster, than whatever async scheme you can come up with. // will be as fast, if not faster, than whatever async scheme you can come up with.
UpdateProgressWithInfoInit(NULL, FALSE);
for (wb = 0; ; wb += wSize) { for (wb = 0; ; wb += wSize) {
if (img_save->Type == IMG_SAVE_TYPE_ISO) { if (img_save->Type == IMG_SAVE_TYPE_ISO) {
// Optical drives do not appear to increment the sectors to read automatically // Optical drives do not appear to increment the sectors to read automatically
@ -3007,7 +3006,7 @@ DWORD WINAPI SaveImageThread(void* param)
} }
if (rSize == 0) if (rSize == 0)
break; break;
UPDATE_PERCENT(MSG_261, (100.0f*wb)/(1.0f*img_save->DeviceSize)); UpdateProgressWithInfo(OP_FORMAT, MSG_261, wb, img_save->DeviceSize);
for (i = 1; i <= WRITE_RETRIES; i++) { for (i = 1; i <= WRITE_RETRIES; i++) {
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
s = WriteFile(hDestImage, buffer, rSize, &wSize, NULL); s = WriteFile(hDestImage, buffer, rSize, &wSize, NULL);

View file

@ -157,10 +157,6 @@ typedef struct {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|err; \ FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|err; \
goto out; } while(0) goto out; } while(0)
#define UPDATE_PERCENT(msg, percent) if (GetTickCount64() > LastRefresh + MAX_REFRESH) { \
LastRefresh = GetTickCount64(); PrintInfo(0, msg, percent); \
UpdateProgress(OP_FORMAT, percent); }
// For ext2/ext3/ext4 formatting // For ext2/ext3/ext4 formatting
typedef struct { typedef struct {
uint64_t max_size; uint64_t max_size;

View file

@ -445,6 +445,8 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
if ((p_udf_dirent == NULL) || (psz_path == NULL)) if ((p_udf_dirent == NULL) || (psz_path == NULL))
return 1; return 1;
if (psz_path[0] == 0)
UpdateProgressWithInfoInit(NULL, TRUE);
while ((p_udf_dirent = udf_readdir(p_udf_dirent)) != NULL) { while ((p_udf_dirent = udf_readdir(p_udf_dirent)) != NULL) {
if (FormatStatus) goto out; if (FormatStatus) goto out;
psz_basename = udf_get_filename(p_udf_dirent); psz_basename = udf_get_filename(p_udf_dirent);
@ -524,7 +526,7 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
} }
file_length -= read; file_length -= read;
if (nb_blocks++ % PROGRESS_THRESHOLD == 0) if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks); UpdateProgressWithInfo(OP_FILE_COPY, MSG_231, nb_blocks, total_blocks);
} }
} }
if ((preserve_timestamps) && (!SetFileTime(file_handle, to_filetime(udf_get_attribute_time(p_udf_dirent)), if ((preserve_timestamps) && (!SetFileTime(file_handle, to_filetime(udf_get_attribute_time(p_udf_dirent)),
@ -586,6 +588,8 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
return 1; return 1;
} }
if (psz_path[0] == 0)
UpdateProgressWithInfoInit(NULL, TRUE);
_CDIO_LIST_FOREACH(p_entnode, p_entlist) { _CDIO_LIST_FOREACH(p_entnode, p_entlist) {
if (FormatStatus) goto out; if (FormatStatus) goto out;
p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode); p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode);
@ -677,7 +681,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
} }
extent_length -= ISO_BLOCKSIZE; extent_length -= ISO_BLOCKSIZE;
if (nb_blocks++ % PROGRESS_THRESHOLD == 0) if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks); UpdateProgressWithInfo(OP_FILE_COPY, MSG_231, nb_blocks, total_blocks);
} }
} }
} }
@ -764,7 +768,7 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
} else { } else {
uprintf("Extracting files...\n"); uprintf("Extracting files...\n");
IGNORE_RETVAL(_chdirU(app_dir)); IGNORE_RETVAL(_chdirU(app_dir));
PrintInfo(0, MSG_231); // PrintInfo(0, MSG_231);
if (total_blocks == 0) { if (total_blocks == 0) {
uprintf("Error: ISO has not been properly scanned.\n"); uprintf("Error: ISO has not been properly scanned.\n");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN);

View file

@ -316,7 +316,6 @@ uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer
const char* short_name; const char* short_name;
unsigned char buf[DOWNLOAD_BUFFER_SIZE]; unsigned char buf[DOWNLOAD_BUFFER_SIZE];
char hostname[64], urlpath[128], strsize[32]; char hostname[64], urlpath[128], strsize[32];
HWND hProgressBar = NULL;
BOOL r = FALSE; BOOL r = FALSE;
DWORD dwSize, dwWritten, dwDownloaded; DWORD dwSize, dwWritten, dwDownloaded;
HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hFile = INVALID_HANDLE_VALUE;
@ -343,16 +342,8 @@ uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer
FormatStatus = 0; FormatStatus = 0;
DownloadStatus = 404; DownloadStatus = 404;
if (hProgressDialog != NULL) { if (hProgressDialog != NULL)
// Use the progress control provided, if any UpdateProgressWithInfoInit(hProgressDialog, FALSE);
hProgressBar = GetDlgItem(hProgressDialog, IDC_PROGRESS);
if (hProgressBar != NULL) {
SendMessage(hProgressBar, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0);
SendMessage(hProgressBar, PBM_SETMARQUEE, FALSE, 0);
SendMessage(hProgressBar, PBM_SETPOS, 0, 0);
}
SendMessage(hProgressDialog, UM_PROGRESS_INIT, 0, 0);
}
assert(url != NULL); assert(url != NULL);
if (buffer != NULL) if (buffer != NULL)
@ -449,12 +440,8 @@ uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer
goto out; goto out;
if (!pfInternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0)) if (!pfInternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0))
break; break;
if (hProgressDialog != NULL) { if (hProgressDialog != NULL)
SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)((1.0f * MAX_PROGRESS * size) / (1.0f * total_size)), 0); UpdateProgressWithInfo(OP_NOOP, MSG_241, size, total_size);
if (bTaskBarProgress)
SetTaskbarProgressValue((ULONGLONG)((1.0f * MAX_PROGRESS * size) / (1.0f * total_size)), MAX_PROGRESS);
PrintInfo(0, MSG_241, (100.0f*size) / (1.0f*total_size));
}
if (file != NULL) { if (file != NULL) {
if (!WriteFile(hFile, buf, dwDownloaded, &dwWritten, NULL)) { if (!WriteFile(hFile, buf, dwDownloaded, &dwWritten, NULL)) {
uprintf("Error writing file '%s': %s", short_name, WinInetErrorString()); uprintf("Error writing file '%s': %s", short_name, WinInetErrorString());
@ -477,9 +464,8 @@ uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer
DownloadStatus = 200; DownloadStatus = 200;
r = TRUE; r = TRUE;
if (hProgressDialog != NULL) { if (hProgressDialog != NULL) {
UpdateProgressWithInfo(OP_NOOP, MSG_241, total_size, total_size);
uprintf("Successfully downloaded '%s'", short_name); uprintf("Successfully downloaded '%s'", short_name);
SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)MAX_PROGRESS, 0);
PrintInfo(0, MSG_241, 100.0f);
} }
} }

View file

@ -2870,6 +2870,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
FILE* fd; FILE* fd;
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount = TRUE; BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount = TRUE;
BOOL disable_hogger = FALSE, previous_enable_HDDs = FALSE, vc = IsRegistryNode(REGKEY_HKCU, vs_reg); BOOL disable_hogger = FALSE, previous_enable_HDDs = FALSE, vc = IsRegistryNode(REGKEY_HKCU, vs_reg);
BOOL alt_pressed = FALSE, alt_command = FALSE;
BYTE *loc_data; BYTE *loc_data;
DWORD loc_size, size; DWORD loc_size, size;
char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH] = "", ini_flags[] = "rb"; char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH] = "", ini_flags[] = "rb";
@ -3245,6 +3246,12 @@ relaunch:
// ** ***** **** ** ********** // ** ***** **** ** **********
// .,ABCDEFGHIJKLMNOPQRSTUVWXYZ // .,ABCDEFGHIJKLMNOPQRSTUVWXYZ
// Sigh... The things one need to do to detect standalone use of the 'Alt' key.
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam != VK_MENU))
alt_command = TRUE;
else if (GetAsyncKeyState(VK_MENU))
alt_pressed = TRUE;
// Ctrl-A => Select the log data // Ctrl-A => Select the log data
if ( (IsWindowVisible(hLogDialog)) && (GetKeyState(VK_CONTROL) & 0x8000) && if ( (IsWindowVisible(hLogDialog)) && (GetKeyState(VK_CONTROL) & 0x8000) &&
(msg.message == WM_KEYDOWN) && (msg.wParam == 'A') ) { (msg.message == WM_KEYDOWN) && (msg.wParam == 'A') ) {
@ -3478,6 +3485,15 @@ relaunch:
continue; continue;
} }
// Standalone 'Alt' key toggles progress report between percent, rate (if available)
// and remaining time (if availabe)
if (alt_pressed && !GetAsyncKeyState(VK_MENU)) {
alt_pressed = FALSE;
if (!alt_command)
update_progress_type = (update_progress_type + 1) % UPT_MAX;
alt_command = FALSE;
}
// Let the system handle dialog messages (e.g. those from the tab key) // Let the system handle dialog messages (e.g. those from the tab key)
if (!IsDialogMessage(hDlg, &msg) && !IsDialogMessage(hLogDialog, &msg)) { if (!IsDialogMessage(hDlg, &msg) && !IsDialogMessage(hLogDialog, &msg)) {
TranslateMessage(&msg); TranslateMessage(&msg);

View file

@ -224,14 +224,17 @@ enum timer_type {
/* Action type, for progress bar breakdown */ /* Action type, for progress bar breakdown */
enum action_type { enum action_type {
OP_ANALYZE_MBR, OP_NOOP_WITH_TASKBAR = -3,
OP_NOOP = -2,
OP_INIT = -1,
OP_ANALYZE_MBR = 0,
OP_BADBLOCKS, OP_BADBLOCKS,
OP_ZERO_MBR, OP_ZERO_MBR,
OP_PARTITION, OP_PARTITION,
OP_FORMAT, OP_FORMAT,
OP_CREATE_FS, OP_CREATE_FS,
OP_FIX_MBR, OP_FIX_MBR,
OP_DOS, OP_FILE_COPY,
OP_FINALIZE, OP_FINALIZE,
OP_MAX OP_MAX
}; };
@ -472,10 +475,13 @@ extern void PrintStatusInfo(BOOL info, BOOL debug, unsigned int duration, int ms
#define PrintInfo(...) PrintStatusInfo(TRUE, FALSE, __VA_ARGS__) #define PrintInfo(...) PrintStatusInfo(TRUE, FALSE, __VA_ARGS__)
#define PrintInfoDebug(...) PrintStatusInfo(TRUE, TRUE, __VA_ARGS__) #define PrintInfoDebug(...) PrintStatusInfo(TRUE, TRUE, __VA_ARGS__)
extern void UpdateProgress(int op, float percent); extern void UpdateProgress(int op, float percent);
extern void UpdateProgressWithInfo(int op, int msg, uint64_t processed, uint64_t total);
#define UpdateProgressWithInfoInit(hProgressDialog, bNoAltMode) UpdateProgressWithInfo(OP_INIT, (int)bNoAltMode, (uint64_t)(uintptr_t)hProgressDialog, 0);
extern const char* StrError(DWORD error_code, BOOL use_default_locale); extern const char* StrError(DWORD error_code, BOOL use_default_locale);
extern char* GuidToString(const GUID* guid); extern char* GuidToString(const GUID* guid);
extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units); extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units);
extern char* TimestampToHumanReadable(uint64_t ts); extern char* TimestampToHumanReadable(uint64_t ts);
extern char* RateToHumanReadable(uint64_t transferred, uint64_t total);
extern HWND MyCreateDialog(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc); extern HWND MyCreateDialog(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc);
extern INT_PTR MyDialogBox(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc); extern INT_PTR MyDialogBox(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc);
extern void CenterDialog(HWND hDlg, HWND hParent); extern void CenterDialog(HWND hDlg, HWND hParent);
@ -505,7 +511,6 @@ extern char* MountISO(const char* path);
extern void UnMountISO(void); extern void UnMountISO(void);
extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs); extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs);
extern uint16_t GetSyslinuxVersion(char* buf, size_t buf_size, char** ext); extern uint16_t GetSyslinuxVersion(char* buf, size_t buf_size, char** ext);
extern BOOL CreateProgress(void);
extern BOOL SetAutorun(const char* path); extern BOOL SetAutorun(const char* path);
extern char* FileDialog(BOOL save, char* path, const ext_t* ext, DWORD options); extern char* FileDialog(BOOL save, char* path, const ext_t* ext, DWORD options);
extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size); extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
@ -524,7 +529,6 @@ extern BOOL CheckForUpdates(BOOL force);
extern void DownloadNewVersion(void); extern void DownloadNewVersion(void);
extern BOOL DownloadISO(void); extern BOOL DownloadISO(void);
extern BOOL IsDownloadable(const char* url); extern BOOL IsDownloadable(const char* url);
extern const char* ResolveRedirect(const char* url);
extern BOOL IsShown(HWND hDlg); extern BOOL IsShown(HWND hDlg);
extern char* get_token_data_file_indexed(const char* token, const char* filename, int index); extern char* get_token_data_file_indexed(const char* token, const char* filename, int index);
#define get_token_data_file(token, filename) get_token_data_file_indexed(token, filename, 1) #define get_token_data_file(token, filename) get_token_data_file_indexed(token, filename, 1)

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326 IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 3.7.1562" CAPTION "Rufus 3.7.1563"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0 FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -394,8 +394,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,7,1562,0 FILEVERSION 3,7,1563,0
PRODUCTVERSION 3,7,1562,0 PRODUCTVERSION 3,7,1563,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -413,13 +413,13 @@ BEGIN
VALUE "Comments", "https://akeo.ie" VALUE "Comments", "https://akeo.ie"
VALUE "CompanyName", "Akeo Consulting" VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.7.1562" VALUE "FileVersion", "3.7.1563"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus-3.7.exe" VALUE "OriginalFilename", "rufus-3.7.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.7.1562" VALUE "ProductVersion", "3.7.1563"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -695,6 +695,29 @@ char* TimestampToHumanReadable(uint64_t ts)
return str; return str;
} }
// TODO: Add granularity
char* RateToHumanReadable(uint64_t transferred, uint64_t total)
{
const uint64_t refresh_rate = 1000;
static uint64_t start_time, last_refresh = 0;
uint64_t current_time, rate;
if (total == 0) {
// init
start_time = GetTickCount64();
last_refresh = start_time;
} else {
current_time = GetTickCount64();
if (current_time <= start_time)
return NULL;
rate = (transferred * 1000) / (current_time - start_time);
if (current_time > last_refresh + refresh_rate) {
last_refresh = current_time;
uprintf("%s/s", SizeToHumanReadable(rate, FALSE, FALSE));
}
}
return NULL;
}
// Convert custom error code to messages // Convert custom error code to messages
const char* _StrError(DWORD error_code) const char* _StrError(DWORD error_code)
{ {

View file

@ -219,7 +219,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int file_system)
uprintf("Successfully wrote '%s'", &path[3]); uprintf("Successfully wrote '%s'", &path[3]);
if (boot_type != BT_IMAGE) if (boot_type != BT_IMAGE)
UpdateProgress(OP_DOS, -1.0f); UpdateProgress(OP_FILE_COPY, -1.0f);
/* Now flush the media */ /* Now flush the media */
if (!FlushFileBuffers(f_handle)) { if (!FlushFileBuffers(f_handle)) {
@ -380,7 +380,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int file_system)
} }
if (boot_type != BT_IMAGE) if (boot_type != BT_IMAGE)
UpdateProgress(OP_DOS, -1.0f); UpdateProgress(OP_FILE_COPY, -1.0f);
r = TRUE; r = TRUE;

View file

@ -44,6 +44,8 @@
UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU; UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU;
HIMAGELIST hUpImageList, hDownImageList; HIMAGELIST hUpImageList, hDownImageList;
extern BOOL enable_fido, use_vds; extern BOOL enable_fido, use_vds;
// TODO: Use an enum or something
int update_progress_type = UPT_PERCENT;
int advanced_device_section_height, advanced_format_section_height; int advanced_device_section_height, advanced_format_section_height;
// (empty) check box width, (empty) drop down width, button height (for and without dropdown match) // (empty) check box width, (empty) drop down width, button height (for and without dropdown match)
int cbw, ddw, ddbh = 0, bh = 0; int cbw, ddw, ddbh = 0, bh = 0;
@ -1157,16 +1159,16 @@ void InitProgress(BOOL bOnlyFormat)
// 1 extra slot for PBR writing // 1 extra slot for PBR writing
switch (selection_default) { switch (selection_default) {
case BT_MSDOS: case BT_MSDOS:
nb_slots[OP_DOS] = 3 + 1; nb_slots[OP_FILE_COPY] = 3 + 1;
break; break;
case BT_FREEDOS: case BT_FREEDOS:
nb_slots[OP_DOS] = 5 + 1; nb_slots[OP_FILE_COPY] = 5 + 1;
break; break;
case BT_IMAGE: case BT_IMAGE:
nb_slots[OP_DOS] = img_report.is_iso ? -1 : 0; nb_slots[OP_FILE_COPY] = img_report.is_iso ? -1 : 0;
break; break;
default: default:
nb_slots[OP_DOS] = 2 + 1; nb_slots[OP_FILE_COPY] = 2 + 1;
break; break;
} }
} }
@ -1262,6 +1264,69 @@ void UpdateProgress(int op, float percent)
} }
} }
// This updates the progress bar as well as the data displayed on it so that we can
// display percentage completed, rate of transfer and estimated remaining duration.
// During init (op = OP_INIT) an optional HWND can be passed on which to look for
// a progress bar.
void UpdateProgressWithInfo(int op, int msg, uint64_t processed, uint64_t total)
{
HWND hProgressDialog = (HWND)(uintptr_t)processed;
static HWND hProgressBar = NULL;
static uint64_t start_time = 0, last_refresh = 0;
uint64_t rate = 0, current_time = GetTickCount64();
static float percent = 0.0f;
char msg_data[128];
static BOOL bNoAltMode = FALSE;
if (op == OP_INIT) {
start_time = current_time - 1;
last_refresh = 0;
percent = 0.0f;
rate = 0;
hProgressBar = NULL;
bNoAltMode = (BOOL)msg;
if (hProgressDialog != NULL) {
// Use the progress control provided, if any
hProgressBar = GetDlgItem(hProgressDialog, IDC_PROGRESS);
if (hProgressBar != NULL) {
SendMessage(hProgressBar, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0);
SendMessage(hProgressBar, PBM_SETMARQUEE, FALSE, 0);
SendMessage(hProgressBar, PBM_SETPOS, 0, 0);
}
SendMessage(hProgressDialog, UM_PROGRESS_INIT, 0, 0);
}
} else if ((hProgressBar != NULL) || (op > 0)) {
if (processed > total)
processed = total;
percent = (100.0f * processed) / (1.0f * total);
// TODO: Better transfer rate computation using a weighted algorithm such as one from
// https://stackoverflow.com/questions/2779600/how-to-estimate-download-time-remaining-accurately
rate = (current_time == start_time) ? 0 : (processed * 1000) / (current_time - start_time);
if ((processed == total) || (current_time > last_refresh + MAX_REFRESH)) {
if (bNoAltMode)
update_progress_type = 0;
if (update_progress_type == UPT_SPEED) {
static_sprintf(msg_data, "%s/s", SizeToHumanReadable(rate, FALSE, FALSE));
} else if (update_progress_type == UPT_TIME) {
uint64_t seconds = (rate == 0) ? 24 * 3600 : (total - processed) / rate + 1;
static_sprintf(msg_data, "%d:%02d:%02d", (uint32_t)(seconds / 3600), (uint16_t)((seconds % 3600) / 60), (uint16_t)(seconds % 60));
} else {
static_sprintf(msg_data, "%0.1f%%", percent);
}
last_refresh = current_time;
if (op < 0) {
SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS * percent / 100.0f), 0);
if (op == OP_NOOP_WITH_TASKBAR)
SetTaskbarProgressValue((ULONGLONG)(MAX_PROGRESS * percent / 100.0f), MAX_PROGRESS);
} else {
UpdateProgress(op, percent);
}
if (msg >= 0)
PrintInfo(0, msg, msg_data);
}
}
}
void ShowLanguageMenu(RECT rcExclude) void ShowLanguageMenu(RECT rcExclude)
{ {
TPMPARAMS tpm; TPMPARAMS tpm;

View file

@ -43,6 +43,14 @@
TBSTYLE_AUTOSIZE | TBSTYLE_LIST | \ TBSTYLE_AUTOSIZE | TBSTYLE_LIST | \
TBSTYLE_TOOLTIPS ) TBSTYLE_TOOLTIPS )
// Types of update progress we report
enum update_progress_type {
UPT_PERCENT = 0,
UPT_SPEED,
UPT_TIME,
UPT_MAX
};
extern HWND hMultiToolbar, hSaveToolbar, hHashToolbar, hAdvancedDeviceToolbar, hAdvancedFormatToolbar; extern HWND hMultiToolbar, hSaveToolbar, hHashToolbar, hAdvancedDeviceToolbar, hAdvancedFormatToolbar;
extern HFONT hInfoFont; extern HFONT hInfoFont;
extern UINT_PTR UM_LANGUAGE_MENU_MAX; extern UINT_PTR UM_LANGUAGE_MENU_MAX;
@ -53,7 +61,7 @@ extern const char *sfd_name, *flash_type[BADLOCKS_PATTERN_TYPES];
extern char *short_image_path, image_option_txt[128]; extern char *short_image_path, image_option_txt[128];
extern int advanced_device_section_height, advanced_format_section_height; extern int advanced_device_section_height, advanced_format_section_height;
extern int windows_to_go_selection, persistence_unit_selection; extern int windows_to_go_selection, persistence_unit_selection;
extern int selection_default, cbw, ddw, ddbh, bh; extern int selection_default, cbw, ddw, ddbh, bh, update_progress_type;
extern void SetComboEntry(HWND hDlg, int data); extern void SetComboEntry(HWND hDlg, int data);
extern void GetBasicControlsWidth(HWND hDlg); extern void GetBasicControlsWidth(HWND hDlg);

View file

@ -580,7 +580,7 @@ DWORD WINAPI WimProgressCallback(DWORD dwMsgId, WPARAM wParam, LPARAM lParam, PV
// the files have been processed), so we don't use it // the files have been processed), so we don't use it
#if 0 #if 0
PrintInfo(0, MSG_267, (DWORD)wParam); PrintInfo(0, MSG_267, (DWORD)wParam);
UpdateProgress(OP_DOS, 0.98f*(DWORD)wParam); UpdateProgress(OP_FILE_COPY, 0.98f*(DWORD)wParam);
#endif #endif
break; break;
case WIM_MSG_PROCESS: case WIM_MSG_PROCESS:
@ -600,12 +600,12 @@ DWORD WINAPI WimProgressCallback(DWORD dwMsgId, WPARAM wParam, LPARAM lParam, PV
if (wim_proc_files > wim_nb_files) if (wim_proc_files > wim_nb_files)
wim_proc_files = wim_nb_files; wim_proc_files = wim_nb_files;
LastRefresh = GetTickCount64(); LastRefresh = GetTickCount64();
// x^3 progress, so as not to give a better idea right from the onset // x^3 progress, so as to give a better idea right from the onset of the dismal
// as to the dismal speed with which the WIM API can actually apply files... // speed with which the WIM API actually applies files...
apply_percent = 4.636942595f * ((float)wim_proc_files) / ((float)wim_nb_files); apply_percent = 4.636942595f * ((float)wim_proc_files) / ((float)wim_nb_files);
apply_percent = apply_percent * apply_percent * apply_percent; apply_percent = apply_percent * apply_percent * apply_percent;
PrintInfo(0, MSG_267, apply_percent); PrintInfo(0, MSG_267, apply_percent);
UpdateProgress(OP_DOS, apply_percent); UpdateProgress(OP_FILE_COPY, apply_percent);
} }
} }
// Halt on error // Halt on error
@ -710,7 +710,7 @@ static DWORD WINAPI WimApplyImageThread(LPVOID param)
goto out; goto out;
} }
PrintInfo(0, MSG_267, 99.8f); PrintInfo(0, MSG_267, 99.8f);
UpdateProgress(OP_DOS, 99.8f); UpdateProgress(OP_FILE_COPY, 99.8f);
r = TRUE; r = TRUE;
out: out: