mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-21 18:35:26 -04:00
[vhd] add backup to uncompressed VHD image
* Part of #321 * NOTE: This feature will be enabled after the 1.4.8 release
This commit is contained in:
parent
1e121d2025
commit
04bd5116a7
5 changed files with 329 additions and 51 deletions
101
src/format.c
101
src/format.c
|
@ -1397,12 +1397,12 @@ DWORD WINAPI FormatThread(void* param)
|
|||
PrintStatus(0, FALSE, MSG_261, format_percent);
|
||||
UpdateProgress(OP_FORMAT, format_percent);
|
||||
}
|
||||
CHECK_FOR_USER_CANCEL;
|
||||
// Don't overflow our projected size (mostly for VHDs)
|
||||
if (wb + rSize > iso_report.projected_size) {
|
||||
rSize = (DWORD)(iso_report.projected_size - wb);
|
||||
}
|
||||
for (i=0; i<WRITE_RETRIES; i++) {
|
||||
CHECK_FOR_USER_CANCEL;
|
||||
s = WriteFile(hPhysicalDrive, buffer, rSize, &wSize, NULL);
|
||||
if ((s) && (wSize == rSize))
|
||||
break;
|
||||
|
@ -1631,3 +1631,102 @@ out:
|
|||
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
DWORD WINAPI SaveImageThread(void* param)
|
||||
{
|
||||
BOOL s;
|
||||
DWORD rSize, wSize, LastRefresh = 0, DriveIndex = (DWORD)(uintptr_t)param;
|
||||
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
|
||||
HANDLE hDestImage = INVALID_HANDLE_VALUE;
|
||||
LARGE_INTEGER li;
|
||||
uint8_t *buffer = NULL;
|
||||
uint64_t wb;
|
||||
int i;
|
||||
|
||||
PrintStatus(0, TRUE, MSG_225);
|
||||
hPhysicalDrive = GetPhysicalHandle(DriveIndex, FALSE, TRUE);
|
||||
if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Write an image file
|
||||
// We poked the MBR and other stuff, so we need to rewind
|
||||
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, CREATE_ALWAYS, 0, NULL);
|
||||
if (hDestImage == INVALID_HANDLE_VALUE) {
|
||||
uprintf("Could not open image '%s': %s", image_path, WindowsErrorString());
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uprintf("Saving to image '%s'...", image_path);
|
||||
buffer = (uint8_t*)malloc(DD_BUFFER_SIZE);
|
||||
if (buffer == NULL) {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY;
|
||||
uprintf("could not allocate buffer");
|
||||
goto out;
|
||||
}
|
||||
|
||||
// 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.
|
||||
for (wb = 0; ; wb += wSize) {
|
||||
s = ReadFile(hPhysicalDrive, buffer,
|
||||
(DWORD)MIN(DD_BUFFER_SIZE, SelectedDrive.DiskSize - wb), &rSize, NULL);
|
||||
if (!s) {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT;
|
||||
uprintf("read error: %s", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
if (rSize == 0)
|
||||
break;
|
||||
if (GetTickCount() > LastRefresh + 25) {
|
||||
LastRefresh = GetTickCount();
|
||||
format_percent = (100.0f*wb)/(1.0f*SelectedDrive.DiskSize);
|
||||
PrintStatus(0, FALSE, MSG_261, format_percent);
|
||||
UpdateProgress(OP_FORMAT, format_percent);
|
||||
}
|
||||
for (i=0; i<WRITE_RETRIES; i++) {
|
||||
CHECK_FOR_USER_CANCEL;
|
||||
s = WriteFile(hDestImage, buffer, rSize, &wSize, NULL);
|
||||
if ((s) && (wSize == rSize))
|
||||
break;
|
||||
if (s)
|
||||
uprintf("write error: Wrote %d bytes, expected %d bytes\n", wSize, rSize);
|
||||
else
|
||||
uprintf("write error: %s", WindowsErrorString());
|
||||
if (i < WRITE_RETRIES-1) {
|
||||
li.QuadPart = wb;
|
||||
SetFilePointerEx(hDestImage, li, NULL, FILE_BEGIN);
|
||||
uprintf(" RETRYING...\n");
|
||||
} else {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (i >= WRITE_RETRIES) goto out;
|
||||
}
|
||||
if (wb != SelectedDrive.DiskSize) {
|
||||
uprintf("Error: wrote %llu bytes, expected %llu", wb, SelectedDrive.DiskSize);
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
||||
goto out;
|
||||
}
|
||||
uprintf("%llu bytes written", wb);
|
||||
uprintf("Appending VHD footer...");
|
||||
if (!AppendVHDFooter(image_path)) {
|
||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
||||
goto out;
|
||||
}
|
||||
uprintf("Done");
|
||||
|
||||
out:
|
||||
safe_free(buffer);
|
||||
SendMessage(hISOProgressDlg, UM_PROGRESS_EXIT, 0, 0);
|
||||
safe_closehandle(hDestImage);
|
||||
safe_unlockclose(hPhysicalDrive);
|
||||
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
|
||||
ExitThread(0);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue