diff --git a/src/format.c b/src/format.c index 04d3cd15..a3d66d5a 100644 --- a/src/format.c +++ b/src/format.c @@ -1958,7 +1958,8 @@ out: DWORD WINAPI SaveImageThread(void* param) { BOOL s; - DWORD rSize, wSize, DriveIndex = (DWORD)(uintptr_t)param; + DWORD rSize, wSize; + VHD_SAVE *vhd_save = param; HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; HANDLE hDestImage = INVALID_HANDLE_VALUE; LARGE_INTEGER li; @@ -1968,7 +1969,7 @@ DWORD WINAPI SaveImageThread(void* param) PrintInfoDebug(0, MSG_225); LastRefresh = 0; - hPhysicalDrive = GetPhysicalHandle(DriveIndex, FALSE, TRUE); + hPhysicalDrive = GetPhysicalHandle(vhd_save->DeviceNum, FALSE, TRUE); if (hPhysicalDrive == INVALID_HANDLE_VALUE) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; goto out; @@ -1979,15 +1980,15 @@ DWORD WINAPI SaveImageThread(void* param) li.QuadPart = 0; if (!SetFilePointerEx(hPhysicalDrive, li, NULL, FILE_BEGIN)) uprintf("Warning: Unable to rewind device position - wrong data might be copied!"); - hDestImage = CreateFileU(image_path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, + hDestImage = CreateFileU(vhd_save->path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hDestImage == INVALID_HANDLE_VALUE) { - uprintf("Could not open image '%s': %s", image_path, WindowsErrorString()); + uprintf("Could not open image '%s': %s", vhd_save->path, WindowsErrorString()); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; goto out; } - uprintf("Saving to image '%s'...", image_path); + uprintf("Saving to image '%s'...", vhd_save->path); buffer = (uint8_t*)malloc(DD_BUFFER_SIZE); if (buffer == NULL) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; @@ -2041,13 +2042,14 @@ DWORD WINAPI SaveImageThread(void* param) } uprintf("%" PRIu64 " bytes written", wb); uprintf("Appending VHD footer..."); - if (!AppendVHDFooter(image_path)) { + if (!AppendVHDFooter(vhd_save->path)) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; goto out; } uprintf("Done"); out: + safe_free(vhd_save->path); safe_free(buffer); safe_closehandle(hDestImage); safe_unlockclose(hPhysicalDrive); diff --git a/src/rufus.c b/src/rufus.c index e492497c..692c660f 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -2150,53 +2150,6 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA break; #ifdef RUFUS_TEST case IDC_TEST: - if (format_thid != NULL) { - return (INT_PTR)TRUE; - } - FormatStatus = 0; - format_op_in_progress = TRUE; - // Reset all progress bars - SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0); - SetTaskbarProgressState(TASKBAR_NORMAL); - SetTaskbarProgressValue(0, MAX_PROGRESS); - SendMessage(hProgress, PBM_SETPOS, 0, 0); - nDeviceIndex = ComboBox_GetCurSel(hDeviceList); - if (nDeviceIndex != CB_ERR) { - if ((IsChecked(IDC_BOOT)) && (!BootCheck())) { - format_op_in_progress = FALSE; - break; - } - - GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp)); - if (MessageBoxU(hMainDialog, lmprintf(MSG_003, tmp), - APPLICATION_NAME, MB_OKCANCEL|MB_ICONWARNING|MB_IS_RTL) == IDCANCEL) { - format_op_in_progress = FALSE; - break; - } - safe_free(image_path); - image_path = strdup("C:\\Downloads\\my.vhd"); - - // Disable all controls except cancel - EnableControls(FALSE); - DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex); - FormatStatus = 0; - InitProgress(TRUE); - format_thid = CreateThread(NULL, 0, SaveImageThread, (LPVOID)(uintptr_t)DeviceNum, 0, NULL); - if (format_thid == NULL) { - uprintf("Unable to start saving thread"); - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); - PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); - } - uprintf("\r\nSave to image operation started"); - PrintInfo(0, -1); - timer = 0; - safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); - SendMessageA(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTA, - SBT_OWNERDRAW | 1, (LPARAM)szTimer); - SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); - } - if (format_thid == NULL) - format_op_in_progress = FALSE; break; #endif case IDC_ADVANCED: @@ -2970,6 +2923,59 @@ relaunch: GetUSBDevices(0); continue; } + // Alt-V => Save selected device to *UNCOMPRESSED* VHD + if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'V')) { + int DriveIndex = ComboBox_GetCurSel(hDeviceList); + if ((DriveIndex != CB_ERR) && (!format_op_in_progress) && (format_thid == NULL)) { + EXT_DECL(vhd_ext, DriveLabel.String[DriveIndex], __VA_GROUP__("*.vhd"), __VA_GROUP__("VHD File")); + ULARGE_INTEGER free_space; + VHD_SAVE vhd_save = { (DWORD)ComboBox_GetItemData(hDeviceList, DriveIndex), FileDialog(TRUE, NULL, &vhd_ext, 0) }; + if (vhd_save.path != NULL) { + // Reset all progress bars + SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0); + SetTaskbarProgressState(TASKBAR_NORMAL); + SetTaskbarProgressValue(0, MAX_PROGRESS); + SendMessage(hProgress, PBM_SETPOS, 0, 0); + FormatStatus = 0; + format_op_in_progress = TRUE; + free_space.QuadPart = 0; + if ( (GetVolumePathNameA(vhd_save.path, tmp_path, sizeof(tmp_path))) + && (GetDiskFreeSpaceExA(tmp_path, &free_space, NULL, NULL)) + && ((LONGLONG)free_space.QuadPart > (SelectedDrive.DiskSize + 512)) ) { + // Disable all controls except cancel + EnableControls(FALSE); + FormatStatus = 0; + InitProgress(TRUE); + format_thid = CreateThread(NULL, 0, SaveImageThread, &vhd_save, 0, NULL); + if (format_thid != NULL) { + uprintf("\r\nSave to VHD operation started"); + PrintInfo(0, -1); + timer = 0; + safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); + SendMessageA(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTA, SBT_OWNERDRAW | 1, (LPARAM)szTimer); + SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); + } else { + uprintf("Unable to start VHD save thread"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); + safe_free(vhd_save.path); + PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); + format_op_in_progress = FALSE; + } + } else { + if (free_space.QuadPart == 0) { + uprintf("Unable to isolate drive name for VHD save"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PATH_NOT_FOUND; + } else { + uprintf("The VHD size is too large for the target drive"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_FILE_TOO_LARGE; + } + safe_free(vhd_save.path); + PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); + format_op_in_progress = FALSE; + } + } + } + } // Alt-W => Enable VMWare disk detection if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'W')) { enable_vmdk = !enable_vmdk; diff --git a/src/rufus.h b/src/rufus.h index edf17c68..e6d75f15 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -16,7 +16,7 @@ * along with this program. If not, see . */ #include -#include // for DISK_GEOMETRY +#include // for DISK_GEOMETRY #include #include @@ -287,6 +287,11 @@ typedef struct { char* release_notes; } RUFUS_UPDATE; +typedef struct { + DWORD DeviceNum; + char* path; +} VHD_SAVE; + /* * Structure and macros used for the extensions specification of FileDialog() * You can use: diff --git a/src/rufus.rc b/src/rufus.rc index f957ad0f..7f4f2766 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Rufus 2.3.670" +CAPTION "Rufus 2.3.671" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -157,7 +157,7 @@ END IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Rufus 2.3.670" +CAPTION "Rufus 2.3.671" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -283,7 +283,7 @@ END IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 2.3.670" +CAPTION "Rufus 2.3.671" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -415,7 +415,7 @@ END IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 2.3.670" +CAPTION "Rufus 2.3.671" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -671,8 +671,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,3,670,0 - PRODUCTVERSION 2,3,670,0 + FILEVERSION 2,3,671,0 + PRODUCTVERSION 2,3,671,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -689,13 +689,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.3.670" + VALUE "FileVersion", "2.3.671" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "2.3.670" + VALUE "ProductVersion", "2.3.671" END END BLOCK "VarFileInfo" diff --git a/src/vhd.c b/src/vhd.c index 8fdafb67..538346d4 100644 --- a/src/vhd.c +++ b/src/vhd.c @@ -126,7 +126,7 @@ static BOOL Get7ZipPath(void) BOOL AppendVHDFooter(const char* vhd_path) { const char creator_os[4] = VHD_FOOTER_CREATOR_HOST_OS_WINDOWS; - const char creator_app[4] = { 'r', 'u', 'f', 'u' }; + const char creator_app[4] = { 'r', 'u', 'f', 's' }; BOOL r = FALSE; DWORD size; LARGE_INTEGER li;