mirror of
https://github.com/pbatard/rufus.git
synced 2024-09-19 11:08:50 -04:00
[mbr] added some mbr processing
* fix MS's removal of LBA from FS types in partition table * improved GetDriveHandle() * issue a refresh after formatting
This commit is contained in:
parent
6e2fb54480
commit
d20e756765
7 changed files with 414 additions and 126 deletions
|
@ -80,6 +80,7 @@
|
||||||
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<AdditionalIncludeDirectories>..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -95,7 +96,7 @@
|
||||||
<TargetEnvironment>X64</TargetEnvironment>
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\..\msvc;..\..\libwdi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -115,6 +116,7 @@
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<AdditionalIncludeDirectories>..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -133,6 +135,7 @@
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<AdditionalIncludeDirectories>..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>setupapi.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -143,11 +146,47 @@
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\br.c" />
|
||||||
|
<ClCompile Include="..\fat12.c" />
|
||||||
|
<ClCompile Include="..\fat16.c" />
|
||||||
|
<ClCompile Include="..\fat32.c" />
|
||||||
|
<ClCompile Include="..\file.c" />
|
||||||
<ClCompile Include="..\msdos.c" />
|
<ClCompile Include="..\msdos.c" />
|
||||||
<ClCompile Include="..\rufus.c" />
|
<ClCompile Include="..\rufus.c" />
|
||||||
<ClCompile Include="..\stdlg.c" />
|
<ClCompile Include="..\stdlg.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\inc\br.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat12_0x0.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat12_0x3e.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat16fd_0x3e.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat16_0x0.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat16_0x3e.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32fd_0x3f0.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32fd_0x52.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32nt_0x0.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32nt_0x1800.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32nt_0x3f0.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32nt_0x52.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32_0x0.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32_0x3f0.h" />
|
||||||
|
<ClInclude Include="..\inc\br_fat32_0x52.h" />
|
||||||
|
<ClInclude Include="..\inc\fat12.h" />
|
||||||
|
<ClInclude Include="..\inc\fat16.h" />
|
||||||
|
<ClInclude Include="..\inc\fat16fd.h" />
|
||||||
|
<ClInclude Include="..\inc\fat32.h" />
|
||||||
|
<ClInclude Include="..\inc\fat32fd.h" />
|
||||||
|
<ClInclude Include="..\inc\fat32nt.h" />
|
||||||
|
<ClInclude Include="..\inc\file.h" />
|
||||||
|
<ClInclude Include="..\inc\label_11_char.h" />
|
||||||
|
<ClInclude Include="..\inc\mbr_2000.h" />
|
||||||
|
<ClInclude Include="..\inc\mbr_95b.h" />
|
||||||
|
<ClInclude Include="..\inc\mbr_dos.h" />
|
||||||
|
<ClInclude Include="..\inc\mbr_dos_f2.h" />
|
||||||
|
<ClInclude Include="..\inc\mbr_syslinux.h" />
|
||||||
|
<ClInclude Include="..\inc\mbr_vista.h" />
|
||||||
|
<ClInclude Include="..\inc\mbr_win7.h" />
|
||||||
|
<ClInclude Include="..\inc\mbr_zero.h" />
|
||||||
<ClInclude Include="..\msapi_utf8.h" />
|
<ClInclude Include="..\msapi_utf8.h" />
|
||||||
<ClInclude Include="..\msdos.h" />
|
<ClInclude Include="..\msdos.h" />
|
||||||
<ClInclude Include="..\rufus.h" />
|
<ClInclude Include="..\rufus.h" />
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Header Files\inc">
|
||||||
|
<UniqueIdentifier>{ecff9fec-41c4-4ce8-b725-27ee39754cb7}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\rufus.c">
|
<ClCompile Include="..\rufus.c">
|
||||||
|
@ -24,6 +27,21 @@
|
||||||
<ClCompile Include="..\msdos.c">
|
<ClCompile Include="..\msdos.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\fat32.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\file.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\br.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\fat16.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\fat12.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\rufus.h">
|
<ClInclude Include="..\rufus.h">
|
||||||
|
@ -41,6 +59,99 @@
|
||||||
<ClInclude Include="..\msdos.h">
|
<ClInclude Include="..\msdos.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat12_0x0.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat12_0x3e.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat16_0x0.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat16_0x3e.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat16fd_0x3e.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32_0x0.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32_0x3f0.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32_0x52.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32fd_0x3f0.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32fd_0x52.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32nt_0x0.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32nt_0x3f0.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32nt_0x52.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\br_fat32nt_0x1800.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\fat12.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\fat16.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\fat16fd.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\fat32.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\fat32fd.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\fat32nt.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\file.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\label_11_char.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\mbr_95b.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\mbr_2000.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\mbr_dos.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\mbr_dos_f2.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\mbr_syslinux.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\mbr_vista.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\mbr_win7.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\mbr_zero.h">
|
||||||
|
<Filter>Header Files\inc</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\rufus.ico">
|
<None Include="..\rufus.ico">
|
||||||
|
|
|
@ -39,10 +39,13 @@ mv cmd.sed~ cmd.sed
|
||||||
# Run sed to update the nano version
|
# Run sed to update the nano version
|
||||||
# NB: we need to run git add else the modified files may be ignored
|
# NB: we need to run git add else the modified files may be ignored
|
||||||
sed -f cmd.sed ./rufus.rc > ./rufus.rc~
|
sed -f cmd.sed ./rufus.rc > ./rufus.rc~
|
||||||
mv ./rufus.rc~ ./rufus.rc
|
# MinGW's sed has the bad habit of eating CRLFs
|
||||||
|
sed 's/$/\r/' ./rufus.rc~ > ./rufus.rc
|
||||||
|
rm ./rufus.rc~
|
||||||
git add ./rufus.rc
|
git add ./rufus.rc
|
||||||
sed -f cmd.sed ./rufus.h > ./rufus.h~
|
sed -f cmd.sed ./rufus.h > ./rufus.h~
|
||||||
mv ./rufus.h~ ./rufus.h
|
sed 's/$/\r/' ./rufus.h~ > ./rufus.h
|
||||||
|
rm ./rufus.h~
|
||||||
git add ./rufus.h
|
git add ./rufus.h
|
||||||
#sed -f cmd.sed _bm.sh > _bm.sh~
|
#sed -f cmd.sed _bm.sh > _bm.sh~
|
||||||
#mv _bm.sh~ _bm.sh
|
#mv _bm.sh~ _bm.sh
|
||||||
|
|
|
@ -26,6 +26,10 @@ const char* additional_copyrights =
|
||||||
"http://pcunleashed.com\r\n"
|
"http://pcunleashed.com\r\n"
|
||||||
"Freeware\r\n"
|
"Freeware\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
|
"Boot record handling by ms-sys by Henrik Carlqvist:\r\n"
|
||||||
|
"http://ms-sys.sourceforge.net\r\n"
|
||||||
|
"GNU General Public License (GPL) v2 or later\r\n"
|
||||||
|
"\r\n"
|
||||||
"FS Type description from by GNU fdisk:\r\n"
|
"FS Type description from by GNU fdisk:\r\n"
|
||||||
"http://www.gnu.org/software/fdisk\r\n"
|
"http://www.gnu.org/software/fdisk\r\n"
|
||||||
"GNU General Public License (GPL) v3 or later\r\n"
|
"GNU General Public License (GPL) v3 or later\r\n"
|
||||||
|
|
375
rufus.c
375
rufus.c
|
@ -37,6 +37,7 @@
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
|
#include <io.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/
|
||||||
|
@ -47,6 +48,9 @@
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "rufus.h"
|
#include "rufus.h"
|
||||||
#include "sys_types.h"
|
#include "sys_types.h"
|
||||||
|
#include "br.h"
|
||||||
|
#include "fat32.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
#if !defined(GUID_DEVINTERFACE_DISK)
|
#if !defined(GUID_DEVINTERFACE_DISK)
|
||||||
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} };
|
||||||
|
@ -110,8 +114,38 @@ void _uprintf(const char *format, ...)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void DumpBufferHex(unsigned char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
size_t i, j, k, pos;
|
||||||
|
char line[80] = "";
|
||||||
|
|
||||||
void StatusPrintf(const char *format, ...)
|
for (i=0, pos=0; i<size; i+=16) {
|
||||||
|
uprintf("%s\n", line);
|
||||||
|
line[0] = 0;
|
||||||
|
sprintf(&line[strlen(line)], " %08x ", i);
|
||||||
|
for(j=0,k=0; k<16; j++,k++) {
|
||||||
|
if (i+j < size) {
|
||||||
|
sprintf(&line[strlen(line)], "%02x", buffer[i+j]);
|
||||||
|
} else {
|
||||||
|
sprintf(&line[strlen(line)], " ");
|
||||||
|
}
|
||||||
|
sprintf(&line[strlen(line)], " ");
|
||||||
|
}
|
||||||
|
sprintf(&line[strlen(line)], " ");
|
||||||
|
for(j=0,k=0; k<16; j++,k++) {
|
||||||
|
if (i+j < size) {
|
||||||
|
if ((buffer[i+j] < 32) || (buffer[i+j] > 126)) {
|
||||||
|
sprintf(&line[strlen(line)], ".");
|
||||||
|
} else {
|
||||||
|
sprintf(&line[strlen(line)], "%c", buffer[i+j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uprintf("%s\n", line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintStatus(const char *format, ...)
|
||||||
{
|
{
|
||||||
char buf[256], *p = buf;
|
char buf[256], *p = buf;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -146,81 +180,104 @@ static const char* GetPartitionType(BYTE Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open a drive with optional write access - return a drive HANDLE and the drive letter
|
* Open a drive with optional write access - returns a drive HANDLE and the drive letter
|
||||||
|
* or INVALID_HANDLE_VALUE (/!\ which is != NULL /!\) on failure
|
||||||
* This call is quite risky (left unchecked, inadvertently passing 0 as index would
|
* This call is quite risky (left unchecked, inadvertently passing 0 as index would
|
||||||
* return a handle to C:, which we might then proceed to unknowingly repartition!),
|
* return a handle to C:, which we might then proceed to unknowingly repartition!),
|
||||||
* so we apply the following mitigation factors:
|
* so we apply the following mitigation factors:
|
||||||
* - Valid indexes must belong to a specific range [DRIVE_INDEX_MIN; DRIVE_INDEX_MAX]
|
* - Valid indexes must belong to a specific range [DRIVE_INDEX_MIN; DRIVE_INDEX_MAX]
|
||||||
* - When opening for write access, we lock the volume. If that fails, which would
|
* - When opening for write access, we lock the volume. If that fails, which would
|
||||||
* typically be the case on C:\ or any other drive in use, we fail the call
|
* typically be the case on C:\ or any other drive in use, we report failure
|
||||||
* - We report the full path of any drive that was successfully opened for write acces
|
* - We report the full path of any drive that was successfully opened for write acces
|
||||||
*/
|
*/
|
||||||
static BOOL GetDriveHandle(DWORD DriveIndex, HANDLE* hDrive, char* DriveLetter, BOOL bWriteAccess)
|
static HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive)
|
||||||
{
|
{
|
||||||
BOOL r;
|
BOOL r;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
HANDLE hDrive = INVALID_HANDLE_VALUE;
|
||||||
STORAGE_DEVICE_NUMBER_REDEF device_number = {0};
|
STORAGE_DEVICE_NUMBER_REDEF device_number = {0};
|
||||||
char drives[26*4]; /* "D:\", "E:\", etc. */
|
char drives[26*4]; /* "D:\", "E:\", etc. */
|
||||||
char *drive = drives;
|
char *drive = drives;
|
||||||
char drive_name[] = "\\\\.\\#:";
|
char logical_drive[] = "\\\\.\\#:";
|
||||||
|
char physical_drive[24];
|
||||||
|
|
||||||
if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) {
|
if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) {
|
||||||
uprintf("WARNING: Bad index value. Please check your code!\n");
|
uprintf("WARNING: Bad index value. Please check the code!\n");
|
||||||
}
|
}
|
||||||
DriveIndex -= DRIVE_INDEX_MIN;
|
DriveIndex -= DRIVE_INDEX_MIN;
|
||||||
|
|
||||||
size = GetLogicalDriveStringsA(sizeof(drives), drives);
|
// If no drive letter is requested, open a phyical drive
|
||||||
if (size == 0) {
|
if (DriveLetter == NULL) {
|
||||||
uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString());
|
safe_sprintf(physical_drive, sizeof(physical_drive), "\\\\.\\PHYSICALDRIVE%d", DriveIndex);
|
||||||
return FALSE;
|
hDrive = CreateFileA(physical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0),
|
||||||
}
|
|
||||||
if (size > sizeof(drives)) {
|
|
||||||
uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*hDrive = INVALID_HANDLE_VALUE;
|
|
||||||
for ( ;*drive; drive += safe_strlen(drive)+1) {
|
|
||||||
if (!isalpha(*drive))
|
|
||||||
continue;
|
|
||||||
*drive = (char)toupper((int)*drive);
|
|
||||||
if (*drive < 'C') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
safe_sprintf(drive_name, sizeof(drive_name), "\\\\.\\%c:", drive[0]);
|
|
||||||
*hDrive = CreateFileA(drive_name, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0),
|
|
||||||
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
|
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
|
||||||
if (hDrive == INVALID_HANDLE_VALUE) {
|
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||||
uprintf("Could not open drive %c: %s\n", drive[0], WindowsErrorString());
|
uprintf("Could not open drive %s: %s\n", physical_drive, WindowsErrorString());
|
||||||
continue;
|
goto out;
|
||||||
|
}
|
||||||
|
if (bWriteAccess) {
|
||||||
|
uprintf("Caution: Opened %s drive for write access\n", physical_drive);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*DriveLetter = ' ';
|
||||||
|
size = GetLogicalDriveStringsA(sizeof(drives), drives);
|
||||||
|
if (size == 0) {
|
||||||
|
uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (size > sizeof(drives)) {
|
||||||
|
uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives));
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = DeviceIoControl(*hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL,
|
hDrive = INVALID_HANDLE_VALUE;
|
||||||
0, &device_number, sizeof(device_number), &size, NULL);
|
for ( ;*drive; drive += safe_strlen(drive)+1) {
|
||||||
if ((!r) || (size <= 0)) {
|
if (!isalpha(*drive))
|
||||||
uprintf("IOCTL_STORAGE_GET_DEVICE_NUMBER (GetDriveHandle) failed: %s\n", WindowsErrorString());
|
continue;
|
||||||
safe_closehandle(*hDrive);
|
*drive = (char)toupper((int)*drive);
|
||||||
break;
|
if (*drive < 'C') {
|
||||||
}
|
continue;
|
||||||
if (device_number.DeviceNumber == DriveIndex) {
|
}
|
||||||
if (bWriteAccess) {
|
safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]);
|
||||||
if (!DeviceIoControl(*hDrive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL)) {
|
hDrive = CreateFileA(logical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0),
|
||||||
uprintf("Could not get exclusive access to %s: %s\n", drive_name, WindowsErrorString());
|
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
|
||||||
safe_closehandle(*hDrive);
|
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||||
return FALSE;
|
uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString());
|
||||||
}
|
continue;
|
||||||
uprintf("Caution: Opened %s drive for write access\n", drive_name);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
safe_closehandle(*hDrive);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DriveLetter != NULL) {
|
r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL,
|
||||||
|
0, &device_number, sizeof(device_number), &size, NULL);
|
||||||
|
if ((!r) || (size <= 0)) {
|
||||||
|
uprintf("IOCTL_STORAGE_GET_DEVICE_NUMBER failed for device %s: %s\n", logical_drive, WindowsErrorString());
|
||||||
|
} else if (device_number.DeviceNumber == DriveIndex) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
safe_closehandle(hDrive);
|
||||||
|
}
|
||||||
|
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (bWriteAccess) {
|
||||||
|
uprintf("Caution: Opened %s drive for write access\n", logical_drive);
|
||||||
|
}
|
||||||
*DriveLetter = *drive?*drive:' ';
|
*DriveLetter = *drive?*drive:' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*hDrive != INVALID_HANDLE_VALUE);
|
if ((bLockDrive) && (!DeviceIoControl(hDrive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL))) {
|
||||||
|
uprintf("Could not get exclusive access to %s: %s\n", logical_drive, WindowsErrorString());
|
||||||
|
safe_closehandle(hDrive);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return hDrive;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline BOOL UnlockDrive(HANDLE hDrive)
|
||||||
|
{
|
||||||
|
DWORD size;
|
||||||
|
return DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -234,7 +291,8 @@ static BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label)
|
||||||
|
|
||||||
*label = STR_NO_LABEL;
|
*label = STR_NO_LABEL;
|
||||||
|
|
||||||
if (!GetDriveHandle(DriveIndex, &hDrive, DrivePath, FALSE))
|
hDrive = GetDriveHandle(DriveIndex, DrivePath, FALSE, FALSE);
|
||||||
|
if (hDrive == INVALID_HANDLE_VALUE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
safe_closehandle(hDrive);
|
safe_closehandle(hDrive);
|
||||||
*letter = DrivePath[0];
|
*letter = DrivePath[0];
|
||||||
|
@ -250,7 +308,7 @@ static void SetClusterSizes(enum _FSType FSType)
|
||||||
{
|
{
|
||||||
IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize));
|
IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize));
|
||||||
// Don't ask me - just following the MS standard here
|
// Don't ask me - just following the MS standard here
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hClusterSize, ComboBox_AddStringU(hClusterSize, "Default allocation size"), 0x8000));
|
IGNORE_RETVAL(ComboBox_SetItemData(hClusterSize, ComboBox_AddStringU(hClusterSize, "Default allocation size"), 0x1000));
|
||||||
// TODO set value above according to FS selected and default cluster sizes from
|
// TODO set value above according to FS selected and default cluster sizes from
|
||||||
// http://support.microsoft.com/kb/140365
|
// http://support.microsoft.com/kb/140365
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hClusterSize, ComboBox_AddStringU(hClusterSize, "512 bytes"), 0x200));
|
IGNORE_RETVAL(ComboBox_SetItemData(hClusterSize, ComboBox_AddStringU(hClusterSize, "512 bytes"), 0x200));
|
||||||
|
@ -292,7 +350,8 @@ static BOOL GetDriveInfo(void)
|
||||||
|
|
||||||
SelectedDrive.DiskSize = 0;
|
SelectedDrive.DiskSize = 0;
|
||||||
|
|
||||||
if (!GetDriveHandle(SelectedDrive.DeviceNumber, &hDrive, DrivePath, FALSE))
|
hDrive = GetDriveHandle(SelectedDrive.DeviceNumber, DrivePath, FALSE, FALSE);
|
||||||
|
if (hDrive == INVALID_HANDLE_VALUE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
|
r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
|
||||||
|
@ -436,54 +495,6 @@ static BOOL PopulateProperties(int ComboIndex)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WriteSectors(HANDLE hDrive, size_t SectorSize, size_t StartSector, size_t nSectors, void* Buf, size_t BufSize)
|
|
||||||
{
|
|
||||||
LARGE_INTEGER ptr;
|
|
||||||
DWORD Size;
|
|
||||||
|
|
||||||
if (SectorSize * nSectors > BufSize) {
|
|
||||||
uprintf("WriteSectors: Buffer is too small\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr.QuadPart = StartSector*SectorSize;
|
|
||||||
if (!SetFilePointerEx(hDrive, ptr, NULL, FILE_BEGIN)) {
|
|
||||||
uprintf("WriteSectors: Could not access sector %lld - %s\n", StartSector, WindowsErrorString());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!WriteFile(hDrive, Buf, (DWORD)BufSize, &Size, NULL)) || (Size != BufSize)) {
|
|
||||||
uprintf("WriteSectors: Write error - %s\n", WindowsErrorString());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL ReadSectors(HANDLE hDrive, size_t SectorSize, size_t StartSector, size_t nSectors, void* Buf, size_t BufSize)
|
|
||||||
{
|
|
||||||
LARGE_INTEGER ptr;
|
|
||||||
DWORD size;
|
|
||||||
|
|
||||||
if (SectorSize * nSectors > BufSize) {
|
|
||||||
uprintf("ReadSectors: Buffer is too small\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr.QuadPart = StartSector*SectorSize;
|
|
||||||
if (!SetFilePointerEx(hDrive, ptr, NULL, FILE_BEGIN)) {
|
|
||||||
uprintf("ReadSectors: Could not access sector %lld - %s\n", StartSector, WindowsErrorString());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!ReadFile(hDrive, Buf, (DWORD)BufSize, &size, NULL)) || (size != BufSize)) {
|
|
||||||
uprintf("ReadSectors: Write error - %s\n", WindowsErrorString());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a partition table
|
* Create a partition table
|
||||||
*/
|
*/
|
||||||
|
@ -494,7 +505,7 @@ static BOOL CreatePartition(HANDLE hDrive)
|
||||||
BOOL r;
|
BOOL r;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
|
||||||
StatusPrintf("Partitioning...");
|
PrintStatus("Partitioning...");
|
||||||
DriveLayoutEx->PartitionStyle = PARTITION_STYLE_MBR;
|
DriveLayoutEx->PartitionStyle = PARTITION_STYLE_MBR;
|
||||||
DriveLayoutEx->PartitionCount = 4; // Must be multiple of 4 for MBR
|
DriveLayoutEx->PartitionCount = 4; // Must be multiple of 4 for MBR
|
||||||
DriveLayoutEx->Mbr.Signature = GetTickCount();
|
DriveLayoutEx->Mbr.Signature = GetTickCount();
|
||||||
|
@ -508,13 +519,13 @@ static BOOL CreatePartition(HANDLE hDrive)
|
||||||
DriveLayoutEx->PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
|
DriveLayoutEx->PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
|
||||||
switch (ComboBox_GetCurSel(hFileSystem)) {
|
switch (ComboBox_GetCurSel(hFileSystem)) {
|
||||||
case FS_FAT16:
|
case FS_FAT16:
|
||||||
DriveLayoutEx->PartitionEntry[0].Mbr.PartitionType = 0x0e;
|
DriveLayoutEx->PartitionEntry[0].Mbr.PartitionType = 0x0e; // FAT16 LBA
|
||||||
break;
|
break;
|
||||||
case FS_NTFS:
|
case FS_NTFS:
|
||||||
DriveLayoutEx->PartitionEntry[0].Mbr.PartitionType = 0x07;
|
DriveLayoutEx->PartitionEntry[0].Mbr.PartitionType = 0x07; // NTFS
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DriveLayoutEx->PartitionEntry[0].Mbr.PartitionType = 0x0c;
|
DriveLayoutEx->PartitionEntry[0].Mbr.PartitionType = 0x0c; // FAT32 LBA
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// For the remaining partitions, PartitionStyle & PartitionType have already
|
// For the remaining partitions, PartitionStyle & PartitionType have already
|
||||||
|
@ -617,7 +628,7 @@ static BOOL FormatDrive(char DriveLetter)
|
||||||
WCHAR wLabel[128];
|
WCHAR wLabel[128];
|
||||||
|
|
||||||
wDriveRoot[0] = (WCHAR)DriveLetter;
|
wDriveRoot[0] = (WCHAR)DriveLetter;
|
||||||
StatusPrintf("Formatting...");
|
PrintStatus("Formatting...");
|
||||||
PF_INIT_OR_OUT(FormatEx, fmifs);
|
PF_INIT_OR_OUT(FormatEx, fmifs);
|
||||||
|
|
||||||
// TODO: properly set MediaType
|
// TODO: properly set MediaType
|
||||||
|
@ -636,41 +647,125 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a separate thread for the formatting operation
|
* Process the MBR
|
||||||
|
*/
|
||||||
|
static BOOL ProcessMBR(HANDLE hPhysicalDrive)
|
||||||
|
{
|
||||||
|
BOOL r = FALSE;
|
||||||
|
HANDLE hDrive = hPhysicalDrive;
|
||||||
|
FILE fake_fd;
|
||||||
|
unsigned char* buf;
|
||||||
|
size_t SecSize = SelectedDrive.Geometry.BytesPerSector;
|
||||||
|
size_t nSecs = 0x200/min(0x200, SelectedDrive.Geometry.BytesPerSector);
|
||||||
|
|
||||||
|
if (SecSize * nSecs != 0x200) {
|
||||||
|
uprintf("Seriously? A drive where sector size is not a power of 2?!?\n");
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintStatus("Processing MBR...\n");
|
||||||
|
|
||||||
|
fake_fd._ptr = (char*)hPhysicalDrive;
|
||||||
|
fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector;
|
||||||
|
uprintf("I'm %sa boot record\n", is_br(&fake_fd)?"":"NOT ");
|
||||||
|
|
||||||
|
// FormatEx rewrites the MBR and removes the LBA attribute of FAT16
|
||||||
|
// and FAT32 partitions - we need to correct this in the MBR
|
||||||
|
// TODO: something else for bootable GPT
|
||||||
|
buf = (unsigned char*)malloc(SecSize * nSecs);
|
||||||
|
if (buf == NULL) {
|
||||||
|
uprintf("Could not allocate memory for MBR");
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!read_sectors(hDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) {
|
||||||
|
uprintf("Could not read MBR\n");
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
DumpBufferHex(buf, 0x200);
|
||||||
|
switch (ComboBox_GetCurSel(hFileSystem)) {
|
||||||
|
// TODO: check for 0x06 & 0x0b?
|
||||||
|
case FS_FAT16:
|
||||||
|
buf[0x1c2] = 0x0e;
|
||||||
|
break;
|
||||||
|
case FS_FAT32:
|
||||||
|
buf[0x1c2] = 0x0c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!write_sectors(hDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) {
|
||||||
|
uprintf("Could not write MBR\n");
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
safe_free(buf);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa364562%28v=vs.85%29.aspx
|
||||||
|
Dismounting a volume is useful when a volume needs to disappear for a while. For
|
||||||
|
example, an application that changes a volume file system from the FAT file system
|
||||||
|
to the NTFS file system might use the following procedure.
|
||||||
|
|
||||||
|
To change a volume file system
|
||||||
|
|
||||||
|
Open a volume.
|
||||||
|
Lock the volume.
|
||||||
|
Format the volume.
|
||||||
|
Dismount the volume.
|
||||||
|
Unlock the volume.
|
||||||
|
Close the volume handle.
|
||||||
|
|
||||||
|
A dismounting operation removes the volume from the FAT file system awareness.
|
||||||
|
When the operating system mounts the volume, it appears as an NTFS file system volume.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standalone thread for the formatting operation
|
||||||
*/
|
*/
|
||||||
static void __cdecl FormatThread(void* param)
|
static void __cdecl FormatThread(void* param)
|
||||||
{
|
{
|
||||||
DWORD num = (DWORD)(uintptr_t)param;
|
DWORD num = (DWORD)(uintptr_t)param;
|
||||||
HANDLE hDrive;
|
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
|
||||||
BOOL r;
|
HANDLE hLogicalVolume = INVALID_HANDLE_VALUE;
|
||||||
char drive_name[] = "?:";
|
char drive_name[] = "?:";
|
||||||
int i;
|
int i;
|
||||||
|
// DWORD size;
|
||||||
|
|
||||||
if (!GetDriveHandle(num, &hDrive, NULL, TRUE)) {
|
hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE);
|
||||||
|
if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
// At this stage with have both a handle and a lock to the physical drive
|
||||||
|
|
||||||
r = CreatePartition(hDrive);
|
if (!CreatePartition(hPhysicalDrive)) {
|
||||||
safe_closehandle(hDrive);
|
|
||||||
if (!r) {
|
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we can reopen the drive before trying to format it
|
// Make sure we can access the volume again 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_name, FALSE)) {
|
hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, TRUE);
|
||||||
|
if (hLogicalVolume != INVALID_HANDLE_VALUE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i >= 10) {
|
if (i >= 10) {
|
||||||
uprintf("Unable to reopen drive post partitioning\n");
|
uprintf("Could not access volume after partitioning\n");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
safe_closehandle(hDrive);
|
// Handle needs to be closed for FormatEx to be happy - we keep a lock though
|
||||||
|
safe_closehandle(hLogicalVolume);
|
||||||
|
|
||||||
if (!FormatDrive(drive_name[0])) {
|
if (!FormatDrive(drive_name[0])) {
|
||||||
// Error will be set by FormatDrive() in FormatStatus
|
// Error will be set by FormatDrive() in FormatStatus
|
||||||
|
@ -678,12 +773,47 @@ static void __cdecl FormatThread(void* param)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Enable compression on NTFS
|
||||||
|
// TODO: disable indexing on NTFS
|
||||||
|
|
||||||
|
// Ideally we would lock, FSCTL_DISMOUNT_VOLUME, unlock and close our volume
|
||||||
|
// handle, but some explorer versions have problems with volumes disappear
|
||||||
|
// #define VOL_DISMOUNT
|
||||||
|
#ifdef VOL_DISMOUNT
|
||||||
|
// Dismount the volume
|
||||||
|
hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, TRUE);
|
||||||
|
if (hLogicalVolume == INVALID_HANDLE_VALUE) {
|
||||||
|
uprintf("Could not open the volume for dismount\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DeviceIoControl(hLogicalVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &size, NULL)) {
|
||||||
|
uprintf("Could not dismount volume\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!ProcessMBR(hPhysicalDrive)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VOL_DISMOUNT
|
||||||
|
safe_unlockclose(hLogicalVolume);
|
||||||
|
// Sleep(10000);
|
||||||
|
hLogicalVolume = GetDriveHandle(num, drive_name, FALSE, FALSE);
|
||||||
|
if (hLogicalVolume == INVALID_HANDLE_VALUE) {
|
||||||
|
uprintf("Could not re-mount volume\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (IsChecked(IDC_DOSSTARTUP)) {
|
if (IsChecked(IDC_DOSSTARTUP)) {
|
||||||
// TODO: check return value & set bootblock
|
// TODO: check return value & set bootblock
|
||||||
ExtractMSDOS(drive_name);
|
ExtractMSDOS(drive_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
safe_unlockclose(hLogicalVolume);
|
||||||
|
safe_unlockclose(hPhysicalDrive);
|
||||||
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
|
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0);
|
||||||
_endthread();
|
_endthread();
|
||||||
}
|
}
|
||||||
|
@ -794,7 +924,7 @@ static BOOL GetUSBDevices(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IGNORE_RETVAL(ComboBox_SetCurSel(hDeviceList, 0));
|
IGNORE_RETVAL(ComboBox_SetCurSel(hDeviceList, 0));
|
||||||
PostMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_DEVICE, 0);
|
SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_DEVICE, 0);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -805,7 +935,7 @@ static void EnableControls(BOOL bEnable)
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_DEVICE), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_DEVICE), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_CAPACITY), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_CAPACITY), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_FILESYSTEM), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_FILESYSTEM), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_ALLOCSIZE), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_CLUSTERSIZE), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_LABEL), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_LABEL), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_QUICKFORMAT), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_QUICKFORMAT), bEnable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDC_DOSSTARTUP), bEnable);
|
EnableWindow(GetDlgItem(hMainDialog, IDC_DOSSTARTUP), bEnable);
|
||||||
|
@ -888,7 +1018,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
// Operation may have completed in the meantime
|
// Operation may have completed in the meantime
|
||||||
if (format_thid != -1L) {
|
if (format_thid != -1L) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
|
||||||
StatusPrintf("Cancelling - please wait...");
|
PrintStatus("Cancelling - please wait...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (INT_PTR)TRUE;
|
return (INT_PTR)TRUE;
|
||||||
|
@ -905,7 +1035,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
case IDC_DEVICE:
|
case IDC_DEVICE:
|
||||||
switch (HIWORD(wParam)) {
|
switch (HIWORD(wParam)) {
|
||||||
case CBN_SELCHANGE:
|
case CBN_SELCHANGE:
|
||||||
StatusPrintf("%d device%s found.", ComboBox_GetCount(hDeviceList),
|
PrintStatus("%d device%s found.", ComboBox_GetCount(hDeviceList),
|
||||||
(ComboBox_GetCount(hDeviceList)!=1)?"s":"");
|
(ComboBox_GetCount(hDeviceList)!=1)?"s":"");
|
||||||
PopulateProperties(ComboBox_GetCurSel(hDeviceList));
|
PopulateProperties(ComboBox_GetCurSel(hDeviceList));
|
||||||
break;
|
break;
|
||||||
|
@ -968,9 +1098,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
SendMessage(hProgress, PBM_SETRANGE, 0, 100<<16);
|
SendMessage(hProgress, PBM_SETRANGE, 0, 100<<16);
|
||||||
}
|
}
|
||||||
SendMessage(hProgress, PBM_SETPOS, FormatStatus?0:100, 0);
|
SendMessage(hProgress, PBM_SETPOS, FormatStatus?0:100, 0);
|
||||||
StatusPrintf(!IS_ERROR(FormatStatus)?"DONE":
|
|
||||||
((SCODE_CODE(FormatStatus)==ERROR_CANCELLED)?"Cancelled":"FAILED"));
|
|
||||||
EnableControls(TRUE);
|
EnableControls(TRUE);
|
||||||
|
GetUSBDevices();
|
||||||
|
PrintStatus(!IS_ERROR(FormatStatus)?"DONE":
|
||||||
|
((SCODE_CODE(FormatStatus)==ERROR_CANCELLED)?"Cancelled":"FAILED"));
|
||||||
return (INT_PTR)TRUE;
|
return (INT_PTR)TRUE;
|
||||||
}
|
}
|
||||||
return (INT_PTR)FALSE;
|
return (INT_PTR)FALSE;
|
||||||
|
|
2
rufus.h
2
rufus.h
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#define RUFUS_DEBUG
|
#define RUFUS_DEBUG
|
||||||
|
|
||||||
#define APP_VERSION "Rufus v1.0.0.44"
|
#define APP_VERSION "Rufus v1.0.0.45"
|
||||||
#define STR_NO_LABEL "NO_LABEL"
|
#define STR_NO_LABEL "NO_LABEL"
|
||||||
#define RUFUS_CANCELBOX_TITLE "Rufus - Cancellation"
|
#define RUFUS_CANCELBOX_TITLE "Rufus - Cancellation"
|
||||||
#define DRIVE_INDEX_MIN 0x80
|
#define DRIVE_INDEX_MIN 0x80
|
||||||
|
|
BIN
rufus.rc
BIN
rufus.rc
Binary file not shown.
Loading…
Reference in a new issue