mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[core] added formatting
* also added filter for hotplug detection
This commit is contained in:
parent
7280b0c45b
commit
1c302ee594
3 changed files with 246 additions and 11 deletions
|
@ -30,6 +30,11 @@ const char* additional_copyrights =
|
|||
"http://www.gnu.org/software/fdisk\r\n"
|
||||
"GNU General Public License (GPL) v3 or later\r\n"
|
||||
"\r\n"
|
||||
"fmifs.dll usage based on Formatx by Mark Russinovich:\r\n"
|
||||
"http://doc.sch130.nsc.ru/www.sysinternals.com/ntw2k/source/fmifs.shtml\r\n"
|
||||
"http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fmifs\r\n"
|
||||
"Public Domain\r\n"
|
||||
"\r\n"
|
||||
"About and License dialogs inspired by WinSCP\r\n"
|
||||
"Copyright (c) 2000-2011 Martin Prikryl\r\n"
|
||||
"GNU General Public License (GPL) v3 or later";
|
||||
|
|
159
rufus.c
159
rufus.c
|
@ -35,12 +35,9 @@
|
|||
#include <commctrl.h>
|
||||
#include <setupapi.h>
|
||||
#include <winioctl.h>
|
||||
#include <dbt.h>
|
||||
|
||||
// http://doc.sch130.nsc.ru/www.sysinternals.com/ntw2k/source/fmifs.shtml
|
||||
// http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fmifs/
|
||||
//#include <fmifs.h>
|
||||
// http://git.kernel.org/?p=fs/ext2/e2fsprogs.git;a=blob;f=misc/badblocks.c
|
||||
|
||||
// http://ms-sys.sourceforge.net/
|
||||
// http://thestarman.pcministry.com/asm/mbr/MSWIN41.htm
|
||||
|
||||
|
@ -77,6 +74,7 @@ struct {
|
|||
static HWND hDeviceList, hCapacity, hFileSystem, hLabel;
|
||||
static HWND hDeviceTooltip = NULL, hFSTooltip = NULL;
|
||||
static StrArray DriveID, DriveLabel;
|
||||
static DWORD FormatErr;
|
||||
|
||||
#ifdef RUFUS_DEBUG
|
||||
void _uprintf(const char *format, ...)
|
||||
|
@ -282,12 +280,12 @@ static BOOL GetDriveInfo(void)
|
|||
if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) {
|
||||
uprintf("Partition #%d:\n", ++nb_partitions);
|
||||
if (hFSTooltip == NULL) {
|
||||
safe_sprintf(tmp, sizeof(tmp), "Current file system: %s (0x%02X)",
|
||||
safe_sprintf(tmp, sizeof(tmp), "Current file system: %s (0x%02x)",
|
||||
GetPartitionType(DriveLayout->PartitionEntry[i].Mbr.PartitionType),
|
||||
DriveLayout->PartitionEntry[i].Mbr.PartitionType);
|
||||
hFSTooltip = CreateTooltip(hFileSystem, tmp, -1);
|
||||
}
|
||||
uprintf(" Type: %s (0x%02X)\n Boot: %s\n Recognized: %s\n Hidden Sectors: %d\n",
|
||||
uprintf(" Type: %s (0x%02x)\n Boot: %s\n Recognized: %s\n Hidden Sectors: %d\n",
|
||||
GetPartitionType(DriveLayout->PartitionEntry[i].Mbr.PartitionType),
|
||||
DriveLayout->PartitionEntry[i].Mbr.PartitionType,
|
||||
DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
|
||||
|
@ -452,6 +450,7 @@ BOOL CreatePartition(HANDLE hDrive)
|
|||
BOOL r;
|
||||
DWORD size;
|
||||
|
||||
StatusPrintf("Partitioning...");
|
||||
DriveLayoutEx->PartitionStyle = PARTITION_STYLE_MBR;
|
||||
DriveLayoutEx->PartitionCount = 4; // Must be multiple of 4 for MBR
|
||||
DriveLayoutEx->Mbr.Signature = GetTickCount();
|
||||
|
@ -484,15 +483,126 @@ BOOL CreatePartition(HANDLE hDrive)
|
|||
safe_closehandle(hDrive);
|
||||
return FALSE;
|
||||
}
|
||||
StatusPrintf("Successfully Created Partition");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* FormatEx callback. Return FALSE to halt operations
|
||||
*/
|
||||
BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DWORD Action, PVOID Data)
|
||||
{
|
||||
DWORD* percent;
|
||||
int task_number = 0;
|
||||
|
||||
switch(Command) {
|
||||
case FCC_PROGRESS:
|
||||
percent = (DWORD*)Data;
|
||||
// PostMessage(hMainDialog, UM_FORMAT_PROGRESS, (WPARAM)*percent, (LPARAM)0);
|
||||
uprintf("%d percent completed.\n", *percent);
|
||||
break;
|
||||
case FCC_STRUCTURE_PROGRESS: // No progress on quick format
|
||||
uprintf("format task %d/n completed.\n", ++task_number);
|
||||
break;
|
||||
case FCC_DONE:
|
||||
if(*(BOOLEAN*)Data == FALSE) {
|
||||
uprintf("Error while formatting.\n");
|
||||
if (FormatErr == 0)
|
||||
FormatErr = FCC_DONE;
|
||||
}
|
||||
break;
|
||||
case FCC_INCOMPATIBLE_FILE_SYSTEM:
|
||||
uprintf("Incompatible File System\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_ACCESS_DENIED:
|
||||
uprintf("Access denied\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_MEDIA_WRITE_PROTECTED:
|
||||
uprintf("Media is write protected\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_VOLUME_IN_USE:
|
||||
uprintf("Volume is in use\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_CANT_QUICK_FORMAT:
|
||||
uprintf("Cannot quick format this volume\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_BAD_LABEL:
|
||||
uprintf("Bad label\n");
|
||||
break;
|
||||
case FCC_OUTPUT:
|
||||
uprintf("%s\n", ((PTEXTOUTPUT)Data)->Output);
|
||||
break;
|
||||
case FCC_CLUSTER_SIZE_TOO_SMALL:
|
||||
uprintf("Allocation unit size is too small\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_CLUSTER_SIZE_TOO_BIG:
|
||||
uprintf("Allocation unit size is too big\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_VOLUME_TOO_SMALL:
|
||||
uprintf("Volume is too small\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_VOLUME_TOO_BIG:
|
||||
uprintf("Volume is too big\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
case FCC_NO_MEDIA_IN_DRIVE:
|
||||
uprintf("No media\n");
|
||||
FormatErr = Command;
|
||||
break;
|
||||
default:
|
||||
uprintf("FormatExCallback: received unhandled command %X\n", Command);
|
||||
break;
|
||||
}
|
||||
return (FormatErr == 0);
|
||||
}
|
||||
|
||||
BOOL Format(char DriveLetter)
|
||||
{
|
||||
BOOL r = FALSE;
|
||||
PF_DECL(FormatEx);
|
||||
WCHAR wDriveRoot[] = L"?:\\";
|
||||
WCHAR wFSType[32];
|
||||
WCHAR wLabel[128];
|
||||
|
||||
wDriveRoot[0] = (WCHAR)DriveLetter;
|
||||
StatusPrintf("Formatting...");
|
||||
PF_INIT_OR_OUT(FormatEx, fmifs);
|
||||
|
||||
// TODO: properly set MediaType
|
||||
FormatErr = 0;
|
||||
GetWindowText(hFileSystem, wFSType, ARRAYSIZE(wFSType));
|
||||
GetWindowText(hLabel, wLabel, ARRAYSIZE(wLabel));
|
||||
pfFormatEx(wDriveRoot, RemovableMedia, wFSType, wLabel,
|
||||
(IsDlgButtonChecked(hMainDialog, IDC_QUICKFORMAT) == BST_CHECKED),
|
||||
4096, FormatExCallback);
|
||||
if (FormatErr == 0) {
|
||||
uprintf("Format completed.\n");
|
||||
StatusPrintf("Done.");
|
||||
r = TRUE;
|
||||
} else {
|
||||
uprintf("Format error: %X\n", FormatErr);
|
||||
StatusPrintf("FAILED.");
|
||||
}
|
||||
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
|
||||
// TODO: create a thread for this
|
||||
BOOL FormatDrive(DWORD num)
|
||||
{
|
||||
HANDLE hDrive;
|
||||
BOOL r;
|
||||
BOOL r = FALSE;
|
||||
char drive_letter;
|
||||
int i;
|
||||
|
||||
if (!GetDriveHandle(num, &hDrive, NULL, TRUE)) {
|
||||
// TODO: report an error for exclusive access
|
||||
|
@ -500,8 +610,24 @@ BOOL FormatDrive(DWORD num)
|
|||
}
|
||||
|
||||
r = CreatePartition(hDrive);
|
||||
safe_closehandle(hDrive);
|
||||
if (!r) return FALSE;
|
||||
|
||||
// Make sure we can reopen the drive before trying to format it
|
||||
for (i=0; i<10; i++) {
|
||||
Sleep(500);
|
||||
if (GetDriveHandle(num, &hDrive, &drive_letter, FALSE)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= 10) {
|
||||
uprintf("Unable to reopen drive after partitioning\n");
|
||||
return FALSE;
|
||||
}
|
||||
safe_closehandle(hDrive);
|
||||
|
||||
r = Format(drive_letter);
|
||||
|
||||
CloseHandle(hDrive);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -629,8 +755,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
switch (message) {
|
||||
|
||||
case WM_DEVICECHANGE:
|
||||
GetUSBDevices();
|
||||
return (INT_PTR)TRUE;
|
||||
// TODO: also prevent detect during format
|
||||
if ((wParam == DBT_DEVICEARRIVAL) || (wParam == DBT_DEVICEREMOVECOMPLETE)) {
|
||||
GetUSBDevices();
|
||||
return (INT_PTR)TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_INITDIALOG:
|
||||
hMainDialog = hDlg;
|
||||
|
@ -646,8 +776,11 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
CreateStatusBar();
|
||||
// Display the version in the right area of the status bar
|
||||
SendMessageA(GetDlgItem(hDlg, IDC_STATUS), SB_SETTEXTA, SBT_OWNERDRAW | 1, (LPARAM)APP_VERSION);
|
||||
// Create the string array
|
||||
StrArrayCreate(&DriveID, MAX_DRIVES);
|
||||
StrArrayCreate(&DriveLabel, MAX_DRIVES);
|
||||
// Set the quick format checkbox
|
||||
CheckDlgButton(hDlg, IDC_QUICKFORMAT, BST_CHECKED);
|
||||
GetUSBDevices();
|
||||
return (INT_PTR)TRUE;
|
||||
|
||||
|
@ -706,6 +839,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case UM_FORMAT_PROGRESS:
|
||||
uprintf("Got UM_FORMAT_PROGRESS with percent %d\n", (DWORD)wParam);
|
||||
return (INT_PTR)TRUE;
|
||||
|
||||
}
|
||||
return (INT_PTR)FALSE;
|
||||
}
|
||||
|
|
93
rufus.h
93
rufus.h
|
@ -15,6 +15,7 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <winioctl.h> // for MEDIA_TYPE
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -98,6 +99,12 @@ extern void _uprintf(const char *format, ...);
|
|||
#define uprintf(...)
|
||||
#endif
|
||||
|
||||
/* Custom Windows messages */
|
||||
enum user_message_type {
|
||||
UM_FORMAT_PROGRESS = WM_APP,
|
||||
UM_FORMAT_COMPLETED
|
||||
};
|
||||
|
||||
/* Custom notifications */
|
||||
enum MessageType {
|
||||
MSG_INFO,
|
||||
|
@ -106,6 +113,8 @@ enum MessageType {
|
|||
};
|
||||
|
||||
/* File system indexes in our FS combobox */
|
||||
// TODO: FormatEx should support "NTFS", "FAT", "FAT32", "UDF", and "EXFAT" as per
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa819439.aspx
|
||||
enum _FSType {
|
||||
FS_FAT16 = 0,
|
||||
FS_FAT32,
|
||||
|
@ -118,3 +127,87 @@ typedef struct {
|
|||
ULONG DeviceNumber;
|
||||
ULONG PartitionNumber;
|
||||
} STORAGE_DEVICE_NUMBER_REDEF;
|
||||
|
||||
/*
|
||||
* typedefs for the function prototypes. Use the something like:
|
||||
* PF_DECL(FormatEx);
|
||||
* which translates to:
|
||||
* FormatEx_t pfFormatEx = NULL;
|
||||
* in your code, to declare the entrypoint and then use:
|
||||
* PF_INIT(FormatEx, fmifs);
|
||||
* which translates to:
|
||||
* pfFormatEx = (FormatEx_t) GetProcAddress(GetDLLHandle("fmifs"), "FormatEx");
|
||||
* to make it accessible.
|
||||
*/
|
||||
static __inline HMODULE GetDLLHandle(char* szDLLName)
|
||||
{
|
||||
HMODULE h = NULL;
|
||||
if ((h = GetModuleHandleA(szDLLName)) == NULL)
|
||||
h = LoadLibraryA(szDLLName);
|
||||
return h;
|
||||
}
|
||||
#define PF_DECL(proc) proc##_t pf##proc = NULL
|
||||
#define PF_INIT(proc, dllname) pf##proc = (proc##_t) GetProcAddress(GetDLLHandle(#dllname), #proc)
|
||||
#define PF_INIT_OR_OUT(proc, dllname) \
|
||||
PF_INIT(proc, dllname); if (pf##proc == NULL) { \
|
||||
uprintf("unable to access %s DLL: %s", #dllname, \
|
||||
WindowsErrorString()); goto out; }
|
||||
|
||||
/* Callback command types (some errorcode were filled from HPUSBFW V2.2.3 and their
|
||||
designation from msdn.microsoft.com/en-us/library/windows/desktop/aa819439.aspx */
|
||||
typedef enum {
|
||||
FCC_PROGRESS,
|
||||
FCC_DONE_WITH_STRUCTURE,
|
||||
FCC_UNKNOWN2,
|
||||
FCC_INCOMPATIBLE_FILE_SYSTEM,
|
||||
FCC_UNKNOWN4,
|
||||
FCC_UNKNOWN5,
|
||||
FCC_ACCESS_DENIED,
|
||||
FCC_MEDIA_WRITE_PROTECTED,
|
||||
FCC_VOLUME_IN_USE,
|
||||
FCC_CANT_QUICK_FORMAT,
|
||||
FCC_UNKNOWNA,
|
||||
FCC_DONE,
|
||||
FCC_BAD_LABEL,
|
||||
FCC_UNKNOWND,
|
||||
FCC_OUTPUT,
|
||||
FCC_STRUCTURE_PROGRESS,
|
||||
FCC_CLUSTER_SIZE_TOO_SMALL,
|
||||
FCC_CLUSTER_SIZE_TOO_BIG,
|
||||
FCC_VOLUME_TOO_SMALL,
|
||||
FCC_VOLUME_TOO_BIG,
|
||||
FCC_NO_MEDIA_IN_DRIVE,
|
||||
} FILE_SYSTEM_CALLBACK_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
DWORD Lines;
|
||||
CHAR* Output;
|
||||
} TEXTOUTPUT, *PTEXTOUTPUT;
|
||||
|
||||
typedef BOOLEAN (__stdcall *FILE_SYSTEM_CALLBACK)(
|
||||
FILE_SYSTEM_CALLBACK_COMMAND Command,
|
||||
ULONG Action,
|
||||
PVOID Data
|
||||
);
|
||||
|
||||
/* Parameter naming aligned to
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa819439.aspx */
|
||||
typedef VOID (WINAPI *FormatEx_t)(
|
||||
WCHAR* DriveRoot,
|
||||
MEDIA_TYPE MediaType, // See WinIoCtl.h
|
||||
WCHAR* FileSystemTypeName,
|
||||
WCHAR* Label,
|
||||
BOOL QuickFormat,
|
||||
ULONG DesiredUnitAllocationSize,
|
||||
FILE_SYSTEM_CALLBACK Callback
|
||||
);
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa383357.aspx */
|
||||
typedef enum {
|
||||
FPF_COMPRESSED = 0x01
|
||||
} FILE_SYSTEM_PROP_FLAG;
|
||||
|
||||
typedef BOOLEAN (WINAPI* EnableVolumeCompression_t)(
|
||||
WCHAR* DriveRoot,
|
||||
ULONG CompressionFlags // FILE_SYSTEM_PROP_FLAG
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue