mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[core] use separate thread for format
* also added progressbar display * also added copying of MS-DOS files (no bootblock yet)
This commit is contained in:
parent
f75a9fc7cb
commit
99951cdb27
3 changed files with 88 additions and 23 deletions
107
rufus.c
107
rufus.c
|
@ -35,11 +35,13 @@
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <setupapi.h>
|
#include <setupapi.h>
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
#include <process.h>
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
|
|
||||||
// http://git.kernel.org/?p=fs/ext2/e2fsprogs.git;a=blob;f=misc/badblocks.c
|
// http://git.kernel.org/?p=fs/ext2/e2fsprogs.git;a=blob;f=misc/badblocks.c
|
||||||
// http://ms-sys.sourceforge.net/
|
// http://ms-sys.sourceforge.net/
|
||||||
// http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm
|
// http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm
|
||||||
|
// http://www.c-jump.com/CIS24/Slides/FAT/lecture.html#F01_0130_sector_assignments
|
||||||
|
|
||||||
#include "msapi_utf8.h"
|
#include "msapi_utf8.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
@ -50,6 +52,14 @@
|
||||||
const GUID GUID_DEVINTERFACE_DISK = { 0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b} };
|
const GUID GUID_DEVINTERFACE_DISK = { 0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b} };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// For MinGW
|
||||||
|
#ifndef PBS_MARQUEE
|
||||||
|
#define PBS_MARQUEE 0x08
|
||||||
|
#endif
|
||||||
|
#ifndef PBM_SETMARQUEE
|
||||||
|
#define PBM_SETMARQUEE (WM_USER+10)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
|
@ -171,6 +181,9 @@ static BOOL GetDriveHandle(DWORD DriveIndex, HANDLE* hDrive, char* DriveLetter,
|
||||||
|
|
||||||
*hDrive = INVALID_HANDLE_VALUE;
|
*hDrive = INVALID_HANDLE_VALUE;
|
||||||
for ( ;*drive; drive += safe_strlen(drive)+1) {
|
for ( ;*drive; drive += safe_strlen(drive)+1) {
|
||||||
|
if (!isalpha(*drive))
|
||||||
|
continue;
|
||||||
|
*drive = (char)toupper((int)*drive);
|
||||||
if (*drive < 'C') {
|
if (*drive < 'C') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -498,7 +511,7 @@ BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DWORD A
|
||||||
switch(Command) {
|
switch(Command) {
|
||||||
case FCC_PROGRESS:
|
case FCC_PROGRESS:
|
||||||
percent = (DWORD*)Data;
|
percent = (DWORD*)Data;
|
||||||
// PostMessage(hMainDialog, UM_FORMAT_PROGRESS, (WPARAM)*percent, (LPARAM)0);
|
PostMessage(hMainDialog, UM_FORMAT_PROGRESS, (WPARAM)*percent, (LPARAM)0);
|
||||||
uprintf("%d percent completed.\n", *percent);
|
uprintf("%d percent completed.\n", *percent);
|
||||||
break;
|
break;
|
||||||
case FCC_STRUCTURE_PROGRESS: // No progress on quick format
|
case FCC_STRUCTURE_PROGRESS: // No progress on quick format
|
||||||
|
@ -564,7 +577,10 @@ BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DWORD A
|
||||||
return (FormatErr == 0);
|
return (FormatErr == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL Format(char DriveLetter)
|
/*
|
||||||
|
* Call on fmifs.dll's FormatEx() to format the drive
|
||||||
|
*/
|
||||||
|
BOOL FormatDrive(char DriveLetter)
|
||||||
{
|
{
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
PF_DECL(FormatEx);
|
PF_DECL(FormatEx);
|
||||||
|
@ -580,15 +596,15 @@ BOOL Format(char DriveLetter)
|
||||||
FormatErr = 0;
|
FormatErr = 0;
|
||||||
GetWindowTextW(hFileSystem, wFSType, ARRAYSIZE(wFSType));
|
GetWindowTextW(hFileSystem, wFSType, ARRAYSIZE(wFSType));
|
||||||
GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel));
|
GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel));
|
||||||
|
// TODO set sector size
|
||||||
pfFormatEx(wDriveRoot, RemovableMedia, wFSType, wLabel,
|
pfFormatEx(wDriveRoot, RemovableMedia, wFSType, wLabel,
|
||||||
(IsDlgButtonChecked(hMainDialog, IDC_QUICKFORMAT) == BST_CHECKED),
|
IsChecked(IDC_QUICKFORMAT), 4096, FormatExCallback);
|
||||||
4096, FormatExCallback);
|
|
||||||
if (FormatErr == 0) {
|
if (FormatErr == 0) {
|
||||||
uprintf("Format completed.\n");
|
uprintf("Format completed.\n");
|
||||||
StatusPrintf("Done.");
|
StatusPrintf("Done.");
|
||||||
r = TRUE;
|
r = TRUE;
|
||||||
} else {
|
} else {
|
||||||
uprintf("Format error: %X\n", FormatErr);
|
uprintf("Format error: 0x%02x\n", FormatErr);
|
||||||
StatusPrintf("FAILED.");
|
StatusPrintf("FAILED.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,39 +612,55 @@ out:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: create a thread for this
|
/*
|
||||||
BOOL FormatDrive(DWORD num)
|
* Create a separate thread for the formatting operation
|
||||||
|
*/
|
||||||
|
void __cdecl FormatThread(void* param)
|
||||||
{
|
{
|
||||||
|
DWORD num = (DWORD)(uintptr_t)param;
|
||||||
HANDLE hDrive;
|
HANDLE hDrive;
|
||||||
BOOL r = FALSE;
|
BOOL r;
|
||||||
char drive_letter;
|
char drive_name[] = "?:";
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!GetDriveHandle(num, &hDrive, NULL, TRUE)) {
|
if (!GetDriveHandle(num, &hDrive, NULL, TRUE)) {
|
||||||
// TODO: report an error for exclusive access
|
// TODO: use FormatErr to report an error
|
||||||
return FALSE;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = CreatePartition(hDrive);
|
r = CreatePartition(hDrive);
|
||||||
safe_closehandle(hDrive);
|
safe_closehandle(hDrive);
|
||||||
if (!r) return FALSE;
|
if (!r) {
|
||||||
|
// TODO: use FormatErr to report an error
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure we can reopen the drive before trying to format it
|
// Make sure we can reopen the drive before trying to format it
|
||||||
for (i=0; i<10; i++) {
|
for (i=0; i<10; i++) {
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
if (GetDriveHandle(num, &hDrive, &drive_letter, FALSE)) {
|
if (GetDriveHandle(num, &hDrive, drive_name, FALSE)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i >= 10) {
|
if (i >= 10) {
|
||||||
uprintf("Unable to reopen drive after partitioning\n");
|
uprintf("Unable to reopen drive post partitioning\n");
|
||||||
return FALSE;
|
// TODO: use FormatErr to report an error
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
safe_closehandle(hDrive);
|
safe_closehandle(hDrive);
|
||||||
|
|
||||||
r = Format(drive_letter);
|
if (!FormatDrive(drive_name[0])) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
if (IsChecked(IDC_DOSSTARTUP)) {
|
||||||
|
// TODO: check return value & set bootblock
|
||||||
|
ExtractMSDOS(drive_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
|
||||||
|
_endthread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -750,7 +782,11 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
HDC hDC;
|
HDC hDC;
|
||||||
DRAWITEMSTRUCT* pDI;
|
DRAWITEMSTRUCT* pDI;
|
||||||
int nDeviceIndex;
|
int nDeviceIndex;
|
||||||
|
DWORD DeviceNum;
|
||||||
char str[MAX_PATH], tmp[128];
|
char str[MAX_PATH], tmp[128];
|
||||||
|
static uintptr_t format_thid = -1L;
|
||||||
|
static HWND hProgress;
|
||||||
|
static LONG ProgressStyle = 0;
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
|
|
||||||
|
@ -768,6 +804,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
hCapacity = GetDlgItem(hDlg, IDC_CAPACITY);
|
hCapacity = GetDlgItem(hDlg, IDC_CAPACITY);
|
||||||
hFileSystem = GetDlgItem(hDlg, IDC_FILESYSTEM);
|
hFileSystem = GetDlgItem(hDlg, IDC_FILESYSTEM);
|
||||||
hLabel = GetDlgItem(hDlg, IDC_LABEL);
|
hLabel = GetDlgItem(hDlg, IDC_LABEL);
|
||||||
|
hProgress = GetDlgItem(hDlg, IDC_PROGRESS);
|
||||||
// High DPI scaling
|
// High DPI scaling
|
||||||
hDC = GetDC(hDlg);
|
hDC = GetDC(hDlg);
|
||||||
fScale = GetDeviceCaps(hDC, LOGPIXELSX) / 96.0f;
|
fScale = GetDeviceCaps(hDC, LOGPIXELSX) / 96.0f;
|
||||||
|
@ -776,6 +813,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
CreateStatusBar();
|
CreateStatusBar();
|
||||||
// Display the version in the right area of the status bar
|
// Display the version in the right area of the status bar
|
||||||
SendMessageA(GetDlgItem(hDlg, IDC_STATUS), SB_SETTEXTA, SBT_OWNERDRAW | 1, (LPARAM)APP_VERSION);
|
SendMessageA(GetDlgItem(hDlg, IDC_STATUS), SB_SETTEXTA, SBT_OWNERDRAW | 1, (LPARAM)APP_VERSION);
|
||||||
|
// We'll switch the progressbar to marquee and back => keep a copy of current style
|
||||||
|
ProgressStyle = GetWindowLong(hProgress, GWL_STYLE);
|
||||||
// Create the string array
|
// Create the string array
|
||||||
StrArrayCreate(&DriveID, MAX_DRIVES);
|
StrArrayCreate(&DriveID, MAX_DRIVES);
|
||||||
StrArrayCreate(&DriveLabel, MAX_DRIVES);
|
StrArrayCreate(&DriveLabel, MAX_DRIVES);
|
||||||
|
@ -818,18 +857,32 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
PopulateProperties(ComboBox_GetCurSel(hDeviceList));
|
PopulateProperties(ComboBox_GetCurSel(hDeviceList));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IDC_START:
|
case IDC_START:
|
||||||
|
// TODO: disable all controls and replace Close with Cancel
|
||||||
|
if (format_thid != -1L) {
|
||||||
|
return (INT_PTR)TRUE;
|
||||||
|
}
|
||||||
nDeviceIndex = ComboBox_GetCurSel(hDeviceList);
|
nDeviceIndex = ComboBox_GetCurSel(hDeviceList);
|
||||||
if (nDeviceIndex != CB_ERR) {
|
if (nDeviceIndex != CB_ERR) {
|
||||||
GetWindowTextA(hDeviceList, tmp, sizeof(tmp));
|
GetWindowTextA(hDeviceList, tmp, sizeof(tmp));
|
||||||
safe_sprintf(str, sizeof(str), "WARNING: ALL DATA ON DEVICE %s\r\nWILL BE ERASED!\r\n"
|
safe_sprintf(str, sizeof(str), "WARNING: ALL DATA ON DEVICE %s\r\nWILL BE ERASED!\r\n"
|
||||||
"Do you want to continue with this operation?", tmp);
|
"Do you want to continue with this operation?", tmp);
|
||||||
if (MessageBoxA(hMainDialog, str, "Rufus", MB_OKCANCEL|MB_ICONWARNING) == IDOK) {
|
if (MessageBoxA(hMainDialog, str, "Rufus", MB_OKCANCEL|MB_ICONWARNING) == IDOK) {
|
||||||
FormatDrive((DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex));
|
// Handle marquee progress bar on quickformat
|
||||||
|
SetWindowLongPtr(hProgress, GWL_STYLE, ProgressStyle | (IsChecked(IDC_QUICKFORMAT)?PBS_MARQUEE:0));
|
||||||
|
if (IsChecked(IDC_QUICKFORMAT)) {
|
||||||
|
SendMessage(hProgress, PBM_SETMARQUEE, TRUE, 0);
|
||||||
|
}
|
||||||
|
DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex);
|
||||||
|
format_thid = _beginthread(FormatThread, 0, (void*)(uintptr_t)DeviceNum);
|
||||||
|
if (format_thid == -1L) {
|
||||||
|
// TODO: handle error
|
||||||
|
uprintf("Unable to start formatting thread");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (INT_PTR)FALSE;
|
return (INT_PTR)FALSE;
|
||||||
}
|
}
|
||||||
|
@ -840,14 +893,24 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UM_FORMAT_PROGRESS:
|
case UM_FORMAT_PROGRESS:
|
||||||
uprintf("Got UM_FORMAT_PROGRESS with percent %d\n", (DWORD)wParam);
|
SendMessage(hProgress, PBM_SETPOS, wParam, lParam);
|
||||||
return (INT_PTR)TRUE;
|
return (INT_PTR)TRUE;
|
||||||
|
|
||||||
|
case UM_FORMAT_COMPLETED:
|
||||||
|
format_thid = -1L;
|
||||||
|
if (IsChecked(IDC_QUICKFORMAT))
|
||||||
|
SendMessage(hProgress, PBM_SETMARQUEE, FALSE, 0);
|
||||||
|
SetWindowLongPtr(hProgress, GWL_STYLE, ProgressStyle);
|
||||||
|
// This is the only way to achieve instantenous progress transition
|
||||||
|
SendMessage(hProgress, PBM_SETRANGE, 0, 101<<16);
|
||||||
|
SendMessage(hProgress, PBM_SETPOS, 101, 0);
|
||||||
|
SendMessage(hProgress, PBM_SETRANGE, 0, 100<<16);
|
||||||
|
SendMessage(hProgress, PBM_SETPOS, 100, 0);
|
||||||
|
return (INT_PTR)TRUE;
|
||||||
}
|
}
|
||||||
return (INT_PTR)FALSE;
|
return (INT_PTR)FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Application Entrypoint
|
* Application Entrypoint
|
||||||
*/
|
*/
|
||||||
|
|
2
rufus.h
2
rufus.h
|
@ -37,6 +37,7 @@
|
||||||
#ifndef ARRAYSIZE
|
#ifndef ARRAYSIZE
|
||||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||||
#endif
|
#endif
|
||||||
|
#define IsChecked(CheckBox_ID) (IsDlgButtonChecked(hMainDialog, CheckBox_ID) == BST_CHECKED)
|
||||||
|
|
||||||
#define safe_free(p) do {free((void*)p); p = NULL;} while(0)
|
#define safe_free(p) do {free((void*)p); p = NULL;} while(0)
|
||||||
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
|
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
|
||||||
|
@ -79,6 +80,7 @@ extern HWND CreateTooltip(HWND hControl, const char* message, int duration);
|
||||||
extern void DestroyTooltip(HWND hWnd);
|
extern void DestroyTooltip(HWND hWnd);
|
||||||
extern void DestroyAllTooltips(void);
|
extern void DestroyAllTooltips(void);
|
||||||
extern void Notification(int type, char* text, char* title);
|
extern void Notification(int type, char* text, char* title);
|
||||||
|
extern BOOL ExtractMSDOS(const char* path);
|
||||||
|
|
||||||
/* Basic String Array */
|
/* Basic String Array */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
2
rufus.rc
2
rufus.rc
|
@ -49,7 +49,7 @@ BEGIN
|
||||||
CONTROL "&Quick Format",IDC_QUICKFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,162,58,10
|
CONTROL "&Quick Format",IDC_QUICKFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,162,58,10
|
||||||
CONTROL "Create an &MS-DOS startup disk",IDC_DOSSTARTUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,174,115,10
|
CONTROL "Create an &MS-DOS startup disk",IDC_DOSSTARTUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,174,115,10
|
||||||
LTEXT "New volume &label",IDC_STATIC,17,122,105,10
|
LTEXT "New volume &label",IDC_STATIC,17,122,105,10
|
||||||
CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,15,198,189,9
|
CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,15,198,189,9
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_ABOUTBOX DIALOGEX 0, 0, 287, 195
|
IDD_ABOUTBOX DIALOGEX 0, 0, 287, 195
|
||||||
|
|
Loading…
Reference in a new issue