[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 ""
"Project-Id-Version: 3.5\n"
"Report-Msgid-Bugs-To: pete@akeo.ie\n"
"POT-Creation-Date: 2019-03-12 13:52+0000\n"
"PO-Revision-Date: 2019-04-11 14:19+0100\n"
"POT-Creation-Date: 2019-08-20 17:03+0100\n"
"PO-Revision-Date: 2019-08-20 17:03+0100\n"
"Language: fr_FR\n"
"MIME-Version: 1.0\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"
"Last-Translator: \n"
"Language-Team: \n"
"X-Generator: Poedit 2.2.1\n"
"X-Generator: Poedit 2.2.3\n"
#. • IDD_DIALOG → IDS_DRIVE_PROPERTIES_TXT
msgid "Drive Properties"
@ -1285,8 +1285,8 @@ msgstr "%s sauvegardé"
#. • MSG_217
#.
#. Formatting status (make sure you use a double % to print the percent sign)
msgid "Formatting: %0.1f%% completed"
msgstr "Formatage : %0.1f%% complété"
msgid "Formatting: %s"
msgstr "Formatage : %s"
#. • MSG_218
msgid "Creating file system: Task %d/%d completed"
@ -1335,11 +1335,11 @@ msgid "Closing existing volume..."
msgstr "Fermeture des volumes existants..."
#. • MSG_228
msgid "Writing master boot record..."
msgid "Writing Master Boot Record..."
msgstr "Ecriture du MBR..."
#. • MSG_229
msgid "Writing partition boot record..."
msgid "Writing Partition Boot Record..."
msgstr "Ecriture du PBR..."
#. • MSG_230
@ -1347,8 +1347,8 @@ msgid "Copying DOS files..."
msgstr "Copie des fichiers DOS..."
#. • MSG_231
msgid "Copying ISO files..."
msgstr "Copie des fichiers ISO..."
msgid "Copying ISO files: %s"
msgstr "Copie des fichiers ISO : %s"
#. • MSG_232
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."
#. • MSG_241
msgid "Downloading: %0.1f%%"
msgstr "Téléchargement : %0.1f%%"
msgid "Downloading: %s"
msgstr "Téléchargement : %s"
#. • MSG_242
msgid "Failed to download file."
@ -1485,8 +1485,8 @@ msgid "NTFS compression"
msgstr "Compression NTFS"
#. • MSG_261
msgid "Writing image: %0.1f%% completed"
msgstr "Ecriture d'image : %0.1f%% complété"
msgid "Writing image: %s"
msgstr "Ecriture d'image : %s"
#. • MSG_262
#.
@ -1513,8 +1513,8 @@ msgid "Dual UEFI/BIOS mode"
msgstr "Mode dual UEFI/BIOS"
#. • MSG_267
msgid "Applying Windows image: %0.1f%% completed"
msgstr "Application de l'image Windows : %0.1f%% complété"
msgid "Applying Windows image: %s"
msgstr "Application de l'image Windows : %s"
#. • MSG_268
msgid "Applying Windows image..."
@ -1529,8 +1529,8 @@ msgid "USB debug"
msgstr "Debug USB"
#. • MSG_271
msgid "Computing image checksums: %0.1f%% completed"
msgstr "Calculation des checksums de l'image : %0.1f%% complété"
msgid "Computing image checksums: %s"
msgstr "Calculation des checksums de l'image : %s"
#. • MSG_272
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?"
msgstr ""
"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 ?"
#. • MSG_286
msgid "Zeroing drive: %0.1f%% completed"
msgstr "Effacement à zéro : %0.1f%% complété"
msgid "Zeroing drive: %s"
msgstr "Effacement à zéro : %s"
#. • MSG_287
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.
#. 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"
msgstr "Effacement 'rapide' à zéro : %0.1f%% complété"
msgid "Fast-zeroing drive: %s"
msgstr "Effacement 'rapide' à zéro : %s"

File diff suppressed because it is too large Load Diff

View File

@ -80,18 +80,18 @@ unsigned char ALIGNED(64) buffer[2][BUFFER_SIZE];
/* SHA-256 constants */
static const uint32_t K[64] = {
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
/*
* 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...
*/
typedef struct ALIGNED(64) {
@ -159,10 +159,10 @@ static void sha1_transform(SUM_CONTEXT *ctx, const unsigned char *data)
}
#endif
#define K1 0x5A827999L
#define K2 0x6ED9EBA1L
#define K3 0x8F1BBCDCL
#define K4 0xCA62C1D6L
#define K1 0x5a827999L
#define K2 0x6ed9eba1L
#define K3 0x8f1bbcdcL
#define K4 0xca62c1d6L
#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
#define F2(x,y,z) ( x ^ y ^ z )
#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
@ -170,8 +170,8 @@ static void sha1_transform(SUM_CONTEXT *ctx, const unsigned char *data)
#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f], (x[i&0x0f] = ROL(tm,1)) )
#define SHA1STEP(a,b,c,d,e,f,k,m) do { e += ROL(a, 5) + f(b, c, d) + k + m; \
b = ROL(b, 30); } while(0)
#define SHA1STEP(a, b, c, d, e, f, k, m) do { e += ROL(a, 5) + f(b, c, d) + k + m; \
b = ROL(b, 30); } while(0)
SHA1STEP(a, b, c, d, e, F1, K1, x[0]);
SHA1STEP(e, a, b, c, d, F1, K1, x[1]);
SHA1STEP(d, e, a, b, c, F1, K1, x[2]);
@ -289,19 +289,19 @@ static __inline void sha256_transform(SUM_CONTEXT *ctx, const unsigned char *dat
#define s1(x) (ROR(ROR(x,2)^(x),17)^((x)>>10))
#define BLK0(i) (x[i])
#define BLK2(i) (x[i] += s1(x[((i)-2)&15]) + x[((i)-7)&15] + s0(x[((i)-15)&15]))
#define R(a,b,c,d,e,f,g,h,i) \
#define R(a, b, c, d, e, f, g, h, i) \
h += S1(e) + CH(e,f,g) + K[(i)+(j)] + (j ? BLK2(i) : BLK0(i)); \
d += h; \
h += S0(a) + MAJ(a, b, c)
#define RX_8(i) \
R(a,b,c,d,e,f,g,h, i); \
R(h,a,b,c,d,e,f,g, i+1); \
R(g,h,a,b,c,d,e,f, i+2); \
R(f,g,h,a,b,c,d,e, i+3); \
R(e,f,g,h,a,b,c,d, i+4); \
R(d,e,f,g,h,a,b,c, i+5); \
R(c,d,e,f,g,h,a,b, i+6); \
R(b,c,d,e,f,g,h,a, i+7)
R(a, b, c, d, e, f, g, h, i); \
R(h, a, b, c, d, e, f, g, i+1); \
R(g, h, a, b, c, d, e, f, i+2); \
R(f, g, h, a, b, c, d, e, i+3); \
R(e, f, g, h, a, b, c, d, i+4); \
R(d, e, f, g, h, a, b, c, i+5); \
R(c, d, e, f, g, h, a, b, i+6); \
R(b, c, d, e, f, g, h, a, i+7)
#ifdef BIG_ENDIAN_HOST
memcpy(x, data, sizeof(x));
@ -880,9 +880,8 @@ DWORD WINAPI SumThread(void* param)
DWORD_PTR* thread_affinity = (DWORD_PTR*)param;
HANDLE sum_thread[CHECKSUM_MAX] = { NULL, NULL, NULL };
HANDLE h = INVALID_HANDLE_VALUE;
uint64_t rb, LastRefresh = 0;
uint64_t rb;
int i, _bufnum, r = -1;
float format_percent = 0.0f;
if ((image_path == NULL) || (thread_affinity == NULL))
ExitThread(r);
@ -926,15 +925,10 @@ DWORD WINAPI SumThread(void* param)
bufnum = 0;
_bufnum = 0;
read_size[0] = 1; // Don't trigger the first loop break
UpdateProgressWithInfoInit(hMainDialog, FALSE);
for (rb = 0; ;rb += read_size[_bufnum]) {
// Update the progress and check for cancel
if (GetTickCount64() > LastRefresh + MAX_REFRESH) {
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);
}
UpdateProgressWithInfo(OP_NOOP_WITH_TASKBAR, MSG_271, rb, img_report.image_size);
CHECK_FOR_USER_CANCEL;
// 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) {
r = ExtractFAT(i, (j<3)?path:locale_path);
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);
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);

View File

@ -59,7 +59,6 @@
const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT", "ReFS", "ext2", "ext3", "ext4" };
DWORD FormatStatus = 0, LastWriteError = 0;
badblocks_report report = { 0 };
static uint64_t LastRefresh = 0;
static float format_percent = 0.0f;
static int task_number = 0;
extern const int nb_steps[FS_MAX];
@ -416,7 +415,7 @@ static BOOL FormatFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD Cluste
goto out;
}
PrintInfoDebug(0, MSG_222, "Large FAT32");
LastRefresh = 0;
UpdateProgressWithInfoInit(NULL, TRUE);
VolumeId = GetVolumeID();
// 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) {
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;
if (write_sectors(hLogicalVolume, BytesPerSect, i, BurstSize, pZeroSect) != (BytesPerSect*BurstSize)) {
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;
errcode_t ext2fs_print_progress(int64_t cur_value, int64_t max_value)
{
static int64_t last_value = -1;
if (max_value == 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));
if ((cur_value < last_value) || (cur_value > last_value)) {
last_value = cur_value;
@ -897,7 +897,7 @@ BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LP
FSName = FileSystemLabel[FS_EXT3];
PrintInfoDebug(0, MSG_222, FSName);
LastRefresh = 0;
UpdateProgressWithInfoInit(NULL, TRUE);
// Figure out the volume size and block 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_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,
max((float)ext2fs->group_desc_count / ext2_max_marker, 1.0f));
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') {
// 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 /= 2; // That journal init is really killing us!
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));
goto out;
}
UPDATE_PERCENT(MSG_217, 100.0f);
UpdateProgressWithInfo(OP_FORMAT, MSG_217, 100, 100);
uprintf("Done");
ret = TRUE;
@ -1123,7 +1123,7 @@ static BOOL FormatDriveVds(DWORD DriveIndex, uint64_t PartitionOffset, DWORD Clu
} else {
PrintInfoDebug(0, MSG_222, FSName);
}
LastRefresh = 0;
UpdateProgressWithInfoInit(NULL, TRUE);
VolumeName = GetLogicalName(DriveIndex, PartitionOffset, TRUE, TRUE);
wVolumeName = utf8_to_wchar(VolumeName);
if (wVolumeName == NULL) {
@ -2197,7 +2197,7 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
AltUnmountVolume(ms_efi, FALSE);
}
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
@ -2233,14 +2233,14 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
if (fd != NULL)
fclose(fd);
PrintInfo(0, MSG_267, 100.0f);
UpdateProgress(OP_DOS, 100.0f);
UpdateProgress(OP_FILE_COPY, 100.0f);
return TRUE;
}
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 */
@ -2259,7 +2259,7 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
li.QuadPart = 0;
if (!SetFilePointerEx(hPhysicalDrive, li, NULL, FILE_BEGIN))
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) {
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.
rSize = BufSize;
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) {
s = ReadFile(hSourceImage, buffer, BufSize, &rSize, NULL);
if (!s) {
@ -2834,7 +2834,7 @@ DWORD WINAPI FormatThread(void* param)
if (boot_type != BT_NON_BOOTABLE) {
if ((boot_type == BT_MSDOS) || (boot_type == BT_FREEDOS)) {
UpdateProgress(OP_DOS, -1.0f);
UpdateProgress(OP_FILE_COPY, -1.0f);
PrintInfoDebug(0, MSG_230);
if (!ExtractDOS(drive_name)) {
if (!IS_ERROR(FormatStatus))
@ -2849,7 +2849,7 @@ DWORD WINAPI FormatThread(void* param)
if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE))
uprintf("Failed to copy file: %s", WindowsErrorString());
} 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:'
if (windows_to_go) {
PrintInfoDebug(0, MSG_268);
@ -2859,7 +2859,6 @@ DWORD WINAPI FormatThread(void* param)
goto out;
}
} else {
PrintInfoDebug(0, MSG_231);
if (!ExtractISO(image_path, drive_name, FALSE)) {
if (!IS_ERROR(FormatStatus))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
@ -2948,7 +2947,6 @@ DWORD WINAPI SaveImageThread(void* param)
int i;
PrintInfoDebug(0, MSG_225);
LastRefresh = 0;
switch (img_save->Type) {
case IMG_SAVE_TYPE_VHD:
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:
// 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.
UpdateProgressWithInfoInit(NULL, FALSE);
for (wb = 0; ; wb += wSize) {
if (img_save->Type == IMG_SAVE_TYPE_ISO) {
// Optical drives do not appear to increment the sectors to read automatically
@ -3007,7 +3006,7 @@ DWORD WINAPI SaveImageThread(void* param)
}
if (rSize == 0)
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++) {
CHECK_FOR_USER_CANCEL;
s = WriteFile(hDestImage, buffer, rSize, &wSize, NULL);

View File

@ -157,10 +157,6 @@ typedef struct {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|err; \
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
typedef struct {
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))
return 1;
if (psz_path[0] == 0)
UpdateProgressWithInfoInit(NULL, TRUE);
while ((p_udf_dirent = udf_readdir(p_udf_dirent)) != NULL) {
if (FormatStatus) goto out;
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;
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)),
@ -586,6 +588,8 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
return 1;
}
if (psz_path[0] == 0)
UpdateProgressWithInfoInit(NULL, TRUE);
_CDIO_LIST_FOREACH(p_entnode, p_entlist) {
if (FormatStatus) goto out;
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;
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 {
uprintf("Extracting files...\n");
IGNORE_RETVAL(_chdirU(app_dir));
PrintInfo(0, MSG_231);
// PrintInfo(0, MSG_231);
if (total_blocks == 0) {
uprintf("Error: ISO has not been properly scanned.\n");
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;
unsigned char buf[DOWNLOAD_BUFFER_SIZE];
char hostname[64], urlpath[128], strsize[32];
HWND hProgressBar = NULL;
BOOL r = FALSE;
DWORD dwSize, dwWritten, dwDownloaded;
HANDLE hFile = INVALID_HANDLE_VALUE;
@ -343,16 +342,8 @@ uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer
FormatStatus = 0;
DownloadStatus = 404;
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);
}
if (hProgressDialog != NULL)
UpdateProgressWithInfoInit(hProgressDialog, FALSE);
assert(url != NULL);
if (buffer != NULL)
@ -449,12 +440,8 @@ uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer
goto out;
if (!pfInternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0))
break;
if (hProgressDialog != NULL) {
SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)((1.0f * MAX_PROGRESS * size) / (1.0f * total_size)), 0);
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 (hProgressDialog != NULL)
UpdateProgressWithInfo(OP_NOOP, MSG_241, size, total_size);
if (file != NULL) {
if (!WriteFile(hFile, buf, dwDownloaded, &dwWritten, NULL)) {
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;
r = TRUE;
if (hProgressDialog != NULL) {
UpdateProgressWithInfo(OP_NOOP, MSG_241, total_size, total_size);
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;
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 alt_pressed = FALSE, alt_command = FALSE;
BYTE *loc_data;
DWORD loc_size, size;
char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH] = "", ini_flags[] = "rb";
@ -3245,6 +3246,12 @@ relaunch:
// ** ***** **** ** **********
// .,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
if ( (IsWindowVisible(hLogDialog)) && (GetKeyState(VK_CONTROL) & 0x8000) &&
(msg.message == WM_KEYDOWN) && (msg.wParam == 'A') ) {
@ -3478,6 +3485,15 @@ relaunch:
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)
if (!IsDialogMessage(hDlg, &msg) && !IsDialogMessage(hLogDialog, &msg)) {
TranslateMessage(&msg);

View File

@ -224,14 +224,17 @@ enum timer_type {
/* Action type, for progress bar breakdown */
enum action_type {
OP_ANALYZE_MBR,
OP_NOOP_WITH_TASKBAR = -3,
OP_NOOP = -2,
OP_INIT = -1,
OP_ANALYZE_MBR = 0,
OP_BADBLOCKS,
OP_ZERO_MBR,
OP_PARTITION,
OP_FORMAT,
OP_CREATE_FS,
OP_FIX_MBR,
OP_DOS,
OP_FILE_COPY,
OP_FINALIZE,
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 PrintInfoDebug(...) PrintStatusInfo(TRUE, TRUE, __VA_ARGS__)
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 char* GuidToString(const GUID* guid);
extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units);
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 INT_PTR MyDialogBox(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc);
extern void CenterDialog(HWND hDlg, HWND hParent);
@ -505,7 +511,6 @@ extern char* MountISO(const char* path);
extern void UnMountISO(void);
extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs);
extern uint16_t GetSyslinuxVersion(char* buf, size_t buf_size, char** ext);
extern BOOL CreateProgress(void);
extern BOOL SetAutorun(const char* path);
extern char* FileDialog(BOOL save, char* path, const ext_t* ext, DWORD options);
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 BOOL DownloadISO(void);
extern BOOL IsDownloadable(const char* url);
extern const char* ResolveRedirect(const char* url);
extern BOOL IsShown(HWND hDlg);
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)

View File

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

View File

@ -695,6 +695,29 @@ char* TimestampToHumanReadable(uint64_t ts)
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
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]);
if (boot_type != BT_IMAGE)
UpdateProgress(OP_DOS, -1.0f);
UpdateProgress(OP_FILE_COPY, -1.0f);
/* Now flush the media */
if (!FlushFileBuffers(f_handle)) {
@ -380,7 +380,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int file_system)
}
if (boot_type != BT_IMAGE)
UpdateProgress(OP_DOS, -1.0f);
UpdateProgress(OP_FILE_COPY, -1.0f);
r = TRUE;

View File

@ -44,6 +44,8 @@
UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU;
HIMAGELIST hUpImageList, hDownImageList;
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;
// (empty) check box width, (empty) drop down width, button height (for and without dropdown match)
int cbw, ddw, ddbh = 0, bh = 0;
@ -1157,16 +1159,16 @@ void InitProgress(BOOL bOnlyFormat)
// 1 extra slot for PBR writing
switch (selection_default) {
case BT_MSDOS:
nb_slots[OP_DOS] = 3 + 1;
nb_slots[OP_FILE_COPY] = 3 + 1;
break;
case BT_FREEDOS:
nb_slots[OP_DOS] = 5 + 1;
nb_slots[OP_FILE_COPY] = 5 + 1;
break;
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;
default:
nb_slots[OP_DOS] = 2 + 1;
nb_slots[OP_FILE_COPY] = 2 + 1;
break;
}
}
@ -1229,7 +1231,7 @@ void UpdateProgress(int op, float percent)
return;
}
if (percent > 100.1f) {
// duprintf("UpdateProgress(%d): invalid percentage %0.2f\n", op, percent);
// duprintf("UpdateProgress(%d): invalid percentage %0.2f\n", op, percent);
return;
}
if ((percent < 0.0f) && (nb_slots[op] <= 0)) {
@ -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)
{
TPMPARAMS tpm;

View File

@ -43,6 +43,14 @@
TBSTYLE_AUTOSIZE | TBSTYLE_LIST | \
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 HFONT hInfoFont;
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 int advanced_device_section_height, advanced_format_section_height;
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 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
#if 0
PrintInfo(0, MSG_267, (DWORD)wParam);
UpdateProgress(OP_DOS, 0.98f*(DWORD)wParam);
UpdateProgress(OP_FILE_COPY, 0.98f*(DWORD)wParam);
#endif
break;
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)
wim_proc_files = wim_nb_files;
LastRefresh = GetTickCount64();
// x^3 progress, so as not to give a better idea right from the onset
// as to the dismal speed with which the WIM API can actually apply files...
// x^3 progress, so as to give a better idea right from the onset of the dismal
// speed with which the WIM API actually applies files...
apply_percent = 4.636942595f * ((float)wim_proc_files) / ((float)wim_nb_files);
apply_percent = apply_percent * apply_percent * apply_percent;
PrintInfo(0, MSG_267, apply_percent);
UpdateProgress(OP_DOS, apply_percent);
UpdateProgress(OP_FILE_COPY, apply_percent);
}
}
// Halt on error
@ -710,7 +710,7 @@ static DWORD WINAPI WimApplyImageThread(LPVOID param)
goto out;
}
PrintInfo(0, MSG_267, 99.8f);
UpdateProgress(OP_DOS, 99.8f);
UpdateProgress(OP_FILE_COPY, 99.8f);
r = TRUE;
out: