diff --git a/src/format.c b/src/format.c index e8430272..6257a38b 100644 --- a/src/format.c +++ b/src/format.c @@ -1151,7 +1151,7 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, BOOL bZeroDrive) HANDLE hSourceImage = INVALID_HANDLE_VALUE; DWORD i, read_size[NUM_BUFFERS], write_size, comp_size, buf_size; uint64_t wb, target_size = bZeroDrive ? SelectedDrive.DiskSize : img_report.image_size; - uint64_t cur_value, last_value = UINT64_MAX; + uint64_t cur_value, last_value = 0; int64_t bled_ret; uint8_t* buffer = NULL; uint32_t zero_data, *cmp_buffer = NULL; @@ -1197,11 +1197,9 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, BOOL bZeroDrive) read_size[0] = buf_size; for (wb = 0, write_size = 0; wb < target_size; wb += write_size) { UpdateProgressWithInfo(OP_FORMAT, fast_zeroing ? MSG_306 : MSG_286, wb, target_size); - cur_value = (wb * min(80, target_size)) / target_size; - if (cur_value != last_value) { - last_value = cur_value; + cur_value = (wb * 80) / target_size; + for (; cur_value > last_value && last_value < 80; last_value++) uprintfs("+"); - } // Don't overflow our projected size (mostly for VHDs) if (wb + read_size[0] > target_size) read_size[0] = (DWORD)(target_size - wb); @@ -1275,6 +1273,7 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, BOOL bZeroDrive) if (i > WRITE_RETRIES) goto out; } + uprintfs("\r\n"); } else if (img_report.compression_type != BLED_COMPRESSION_NONE && img_report.compression_type < BLED_COMPRESSION_MAX) { uprintf("Writing compressed image:"); hSourceImage = CreateFileU(image_path, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -1316,8 +1315,9 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, BOOL bZeroDrive) // VHD/VHDX require mounting the image first if (img_report.compression_type == IMG_COMPRESSION_VHD || img_report.compression_type == IMG_COMPRESSION_VHDX) { - vhd_path = VhdMountImage(image_path); - if (vhd_path == NULL) + // Since VHDX images are compressed, we need to obtain the actual size + vhd_path = VhdMountImageAndGetSize(image_path, &target_size); + if (vhd_path == NULL || target_size == 0) goto out; } @@ -1346,11 +1346,12 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, BOOL bZeroDrive) for (wb = 0; read_size[proc_bufnum] != 0; wb += read_size[proc_bufnum]) { // 0. Update the progress UpdateProgressWithInfo(OP_FORMAT, MSG_261, wb, target_size); - cur_value = (wb * min(80, target_size)) / target_size; - if (cur_value != last_value) { - last_value = cur_value; + cur_value = (wb * 80) / target_size; + for ( ; cur_value > last_value && last_value < 80; last_value++) uprintfs("+"); - } + + if (wb >= target_size) + break; // 1. Wait for the current read operation to complete (and update the read size) if ((!WaitFileAsync(hSourceImage, DRIVE_ACCESS_TIMEOUT)) || @@ -1467,7 +1468,7 @@ DWORD WINAPI FormatThread(void* param) extra_partitions |= XP_ESP | XP_MSR; // If we have a bootable image with UEFI bootloaders and the target file system is NTFS or exFAT // or the UEFI:NTFS option is selected, we add the UEFI:NTFS partition... - else if (((boot_type == BT_IMAGE) && IS_EFI_BOOTABLE(img_report)) && ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) || + else if ((((boot_type == BT_IMAGE) && IS_EFI_BOOTABLE(img_report)) && ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT))) || (boot_type == BT_UEFI_NTFS)) { extra_partitions |= XP_UEFI_NTFS; // ...but only if we're not dealing with a Windows image in installer mode with target diff --git a/src/rufus.rc b/src/rufus.rc index cd00d562..de6da44c 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -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 4.5.2113" +CAPTION "Rufus 4.5.2114" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -392,8 +392,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,5,2113,0 - PRODUCTVERSION 4,5,2113,0 + FILEVERSION 4,5,2114,0 + PRODUCTVERSION 4,5,2114,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -411,13 +411,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.5.2113" + VALUE "FileVersion", "4.5.2114" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.5.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.5.2113" + VALUE "ProductVersion", "4.5.2114" END END BLOCK "VarFileInfo" diff --git a/src/vhd.c b/src/vhd.c index 9340079b..1e475a91 100644 --- a/src/vhd.c +++ b/src/vhd.c @@ -908,18 +908,19 @@ PF_TYPE_DECL(WINAPI, DWORD, AttachVirtualDisk, (HANDLE, PSECURITY_DESCRIPTOR, ATTACH_VIRTUAL_DISK_FLAG, ULONG, PATTACH_VIRTUAL_DISK_PARAMETERS, LPOVERLAPPED)); PF_TYPE_DECL(WINAPI, DWORD, DetachVirtualDisk, (HANDLE, DETACH_VIRTUAL_DISK_FLAG, ULONG)); PF_TYPE_DECL(WINAPI, DWORD, GetVirtualDiskPhysicalPath, (HANDLE, PULONG, PWSTR)); -PF_TYPE_DECL(WINAPI, DWORD, GetVirtualDiskOperationProgress, (HANDLE, LPOVERLAPPED, - PVIRTUAL_DISK_PROGRESS)); +PF_TYPE_DECL(WINAPI, DWORD, GetVirtualDiskOperationProgress, (HANDLE, LPOVERLAPPED, PVIRTUAL_DISK_PROGRESS)); +PF_TYPE_DECL(WINAPI, DWORD, GetVirtualDiskInformation, (HANDLE, PULONG, PGET_VIRTUAL_DISK_INFO, PULONG)); static char physical_path[128] = ""; static HANDLE mounted_handle = INVALID_HANDLE_VALUE; -// Mount an ISO or a VHD/VHDX image +// Mount an ISO or a VHD/VHDX image and provide its size // Returns the physical path of the mounted image or NULL on error. -char* VhdMountImage(const char* path) +char* VhdMountImageAndGetSize(const char* path, uint64_t* disk_size) { VIRTUAL_STORAGE_TYPE vtype = { VIRTUAL_STORAGE_TYPE_DEVICE_ISO, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; ATTACH_VIRTUAL_DISK_PARAMETERS vparams = { 0 }; + GET_VIRTUAL_DISK_INFO disk_info = { 0 }; DWORD r; wchar_t wtmp[128]; ULONG size = ARRAYSIZE(wtmp); @@ -929,6 +930,8 @@ char* VhdMountImage(const char* path) PF_INIT_OR_OUT(OpenVirtualDisk, VirtDisk); PF_INIT_OR_OUT(AttachVirtualDisk, VirtDisk); PF_INIT_OR_OUT(GetVirtualDiskPhysicalPath, VirtDisk); + if (disk_size != NULL) + PF_INIT_OR_OUT(GetVirtualDiskInformation, VirtDisk); if (wpath == NULL) return NULL; @@ -967,6 +970,20 @@ char* VhdMountImage(const char* path) goto out; } wchar_to_utf8_no_alloc(wtmp, physical_path, sizeof(physical_path)); + + if (disk_size != NULL) { + *disk_size = 0; + disk_info.Version = GET_VIRTUAL_DISK_INFO_SIZE; + size = sizeof(disk_info); + r = pfGetVirtualDiskInformation(mounted_handle, &size, &disk_info, NULL); + if (r != ERROR_SUCCESS) { + SetLastError(r); + uprintf("Could not obtain virtual size of mounted image '%s': %s", path, WindowsErrorString()); + goto out; + } + *disk_size = disk_info.Size.VirtualSize; + } + ret = physical_path; out: diff --git a/src/vhd.h b/src/vhd.h index 65ac06d9..45a332b2 100644 --- a/src/vhd.h +++ b/src/vhd.h @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Virtual Disk Handling definitions and prototypes - * Copyright © 2022 Pete Batard + * Copyright © 2022-2024 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -135,7 +135,8 @@ extern BOOL WimUnmountImage(const char* image, int index, BOOL commit); extern char* WimGetExistingMountPoint(const char* image, int index); extern BOOL WimIsValidIndex(const char* image, int index); extern int8_t IsBootableImage(const char* path); -extern char* VhdMountImage(const char* path); +extern char* VhdMountImageAndGetSize(const char* path, uint64_t* disksize); +#define VhdMountImage(path) VhdMountImageAndGetSize(path, NULL) extern void VhdUnmountImage(void); extern void VhdSaveImage(void); extern void IsoSaveImage(void);