Skip to content

Commit

Permalink
[core] ensure AutoMount is enabled while the app is running
Browse files Browse the repository at this point in the history
* Having AutoMount disabled when a Fixed drive is being used can
  result in a failure during formatting (issue #386).
* Also set explicit FILE_ATTRIBUTE_NORMAL flag an normalize CreateFile usage
* Closes #386
  • Loading branch information
pbatard committed Nov 11, 2014
1 parent c6fee87 commit d46342c
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/dos.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ static BOOL ExtractFAT(int entry, const char* path)

/* Create a file, using the same attributes as found in the FAT */
hFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, dir_entry->Attributes, 0);
NULL, CREATE_ALWAYS, dir_entry->Attributes, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
uprintf("Unable to create file '%s': %s.\n", filename, WindowsErrorString());
return FALSE;
Expand Down Expand Up @@ -379,8 +379,8 @@ BOOL ExtractFreeDOS(const char* path)
safe_strcpy(filename, sizeof(filename), ((i<2)?path:locale_path));
safe_strcat(filename, sizeof(filename), res_name[i]);

hFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, (i<2)?(FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM):0, 0);
hFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, (i<2)?(FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM):FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
uprintf("Unable to create file '%s': %s.\n", filename, WindowsErrorString());
return FALSE;
Expand Down
52 changes: 48 additions & 4 deletions src/drive.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,48 @@ const GUID PARTITION_BASIC_DATA_GUID =
*/
RUFUS_DRIVE_INFO SelectedDrive;

/*
* The following methods get or set the AutoMount setting (which is different from AutoRun)
* Rufus needs AutoMount to be set as the format process may fail for fixed drives otherwise.
* See https://github.com/pbatard/rufus/issues/386.
*
* Reverse engineering diskpart and mountvol indicates that the former uses the IVdsService
* ClearFlags()/SetFlags() to set VDS_SVF_AUTO_MOUNT_OFF whereas mountvol on uses
* IOCTL_MOUNTMGR_SET_AUTO_MOUNT on "\\\\.\\MountPointManager".
* As the latter is MUCH simpler this is what we'll use too
*/
BOOL SetAutoMount(BOOL enable)
{
HANDLE hMountMgr;
DWORD size;
BOOL ret = FALSE;

hMountMgr = CreateFileA(MOUNTMGR_DOS_DEVICE_NAME, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hMountMgr == NULL)
return FALSE;
ret = DeviceIoControl(hMountMgr, IOCTL_MOUNTMGR_SET_AUTO_MOUNT, &enable, sizeof(enable), NULL, 0, &size, NULL);
CloseHandle(hMountMgr);
return ret;
}

BOOL GetAutoMount(BOOL* enabled)
{
HANDLE hMountMgr;
DWORD size;
BOOL ret = FALSE;

if (enabled == NULL)
return FALSE;
hMountMgr = CreateFileA(MOUNTMGR_DOS_DEVICE_NAME, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hMountMgr == NULL)
return FALSE;
ret = DeviceIoControl(hMountMgr, IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT, NULL, 0, enabled, sizeof(*enabled), &size, NULL);
CloseHandle(hMountMgr);
return ret;
}

/*
* Working with drive indexes quite risky (left unchecked,inadvertently passing 0 as
* index would return a handle to C:, which we might then proceed to unknowingly
Expand All @@ -73,7 +115,7 @@ static HANDLE GetHandle(char* Path, BOOL bWriteAccess, BOOL bLockDrive)
if (Path == NULL)
goto out;
hDrive = CreateFileA(Path, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0),
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDrive == INVALID_HANDLE_VALUE) {
uprintf("Could not open drive %s: %s\n", Path, WindowsErrorString());
goto out;
Expand Down Expand Up @@ -195,7 +237,8 @@ char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent
}

// If we can't have FILE_SHARE_WRITE, forget it
hDrive = CreateFileA(volume_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
hDrive = CreateFileA(volume_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDrive == INVALID_HANDLE_VALUE) {
suprintf("Could not open GUID volume '%s': %s\n", volume_name, WindowsErrorString());
continue;
Expand Down Expand Up @@ -352,7 +395,8 @@ static BOOL _GetDriveLettersAndType(DWORD DriveIndex, char* drive_letters, UINT*
continue;

safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]);
hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDrive == INVALID_HANDLE_VALUE) {
uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString());
continue;
Expand Down Expand Up @@ -727,7 +771,7 @@ static BOOL FlushDrive(char drive_letter)

logical_drive[4] = drive_letter;
hDrive = CreateFileA(logical_drive, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDrive == INVALID_HANDLE_VALUE) {
uprintf("Failed to open %c: for flushing: %s\n", drive_letter, WindowsErrorString());
goto out;
Expand Down
10 changes: 9 additions & 1 deletion src/drive.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@

#pragma once

#define RUFUS_EXTRA_PARTITION_TYPE 0xea
#define RUFUS_EXTRA_PARTITION_TYPE 0xea
#define MOUNTMGRCONTROLTYPE ((ULONG)'m')
#define MOUNTMGR_DOS_DEVICE_NAME "\\\\.\\MountPointManager"
#define IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT \
CTL_CODE(MOUNTMGRCONTROLTYPE, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_MOUNTMGR_SET_AUTO_MOUNT \
CTL_CODE(MOUNTMGRCONTROLTYPE, 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

/* We need a redef of these MS structure */
typedef struct {
Expand All @@ -37,6 +43,8 @@ typedef struct {
DISK_EXTENT Extents[8];
} VOLUME_DISK_EXTENTS_REDEF;

BOOL SetAutoMount(BOOL enable);
BOOL GetAutoMount(BOOL* enabled);
char* GetPhysicalName(DWORD DriveIndex);
HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDrive);
char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent);
Expand Down
9 changes: 6 additions & 3 deletions src/format.c
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,8 @@ static BOOL SetupWinPE(char drive_letter)
}

// At this stage we only handle \i386
handle = CreateFileA(dst, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
handle = CreateFileA(dst, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
uprintf("Could not open %s for patching: %s\n", dst, WindowsErrorString());
goto out;
Expand Down Expand Up @@ -1384,7 +1385,8 @@ DWORD WINAPI FormatThread(void* param)
li.QuadPart = 0;
if (!SetFilePointerEx(hPhysicalDrive, li, NULL, FILE_BEGIN))
uprintf("Warning: Unable to rewind image position - wrong data might be copied!");
hSourceImage = CreateFileU(image_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
hSourceImage = CreateFileU(image_path, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hSourceImage == INVALID_HANDLE_VALUE) {
uprintf("Could not open image '%s': %s", image_path, WindowsErrorString());
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
Expand Down Expand Up @@ -1680,7 +1682,8 @@ 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, CREATE_ALWAYS, 0, NULL);
hDestImage = CreateFileU(image_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());
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
Expand Down
2 changes: 1 addition & 1 deletion src/icon.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ static BOOL SaveIcon(const char* filename)
icondir = (GRPICONDIR*)GetResource(hMainInstance, MAKEINTRESOURCEA(IDI_ICON), _RT_GROUP_ICON, "icon", &res_size, FALSE);

hFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, CREATE_NEW, 0, 0);
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
uprintf("Unable to create icon '%s': %s.\n", filename, WindowsErrorString());
goto out;
Expand Down
22 changes: 18 additions & 4 deletions src/rufus.c
Original file line number Diff line number Diff line change
Expand Up @@ -2089,7 +2089,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
const char* rufus_loc = "rufus.loc";
const char* cmdline_hogger = "rufus.com";
int i, opt, option_index = 0, argc = 0, si = 0, lcid = GetUserDefaultUILanguage();
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE;
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount;
BYTE *loc_data, *hog_data;
DWORD loc_size, hog_size, Size;
char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", *tmp, *locale_name = NULL;
Expand Down Expand Up @@ -2126,8 +2126,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
hogmutex = CreateMutexA(NULL, TRUE, "Global/Rufus_CmdLine");

// Extract the hogger resource
hFile = CreateFileA(cmdline_hogger, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
hFile = CreateFileA(cmdline_hogger, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
// coverity[check_return]
WriteFile(hFile, hog_data, hog_size, &Size, NULL);
Expand Down Expand Up @@ -2219,7 +2219,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
}

hFile = CreateFileU(loc_file, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, 0, 0);
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if ((hFile == INVALID_HANDLE_VALUE) || (!WriteFile(hFile, loc_data, loc_size, &Size, 0)) || (loc_size != Size)) {
uprintf("localization: unable to extract '%s': %s.\n", loc_file, WindowsErrorString());
safe_closehandle(hFile);
Expand Down Expand Up @@ -2277,6 +2277,18 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// 0x9e disables removable and fixed drive notifications
lgp_set = SetLGP(FALSE, &existing_key, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0x9e);

if (nWindowsVersion > WINDOWS_XP) {
// Re-enable AutoMount if needed
if (!GetAutoMount(&automount)) {
uprintf("Could not get AutoMount status");
automount = TRUE; // So that we don't try to change its status on exit
} else if (!automount) {
uprintf("AutoMount was detected as disabled - temporary re-enabling it");
if (!SetAutoMount(TRUE))
uprintf("Failed to enable AutoMount");
}
}

relaunch:
uprintf("localization: using locale '%s'\n", selected_locale->txt[0]);
right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT);
Expand Down Expand Up @@ -2456,6 +2468,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
}
if (lgp_set)
SetLGP(TRUE, &existing_key, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0);
if ((nWindowsVersion > WINDOWS_XP) && (!automount) && (!SetAutoMount(FALSE)))
uprintf("Failed to restore AutoMount to disabled");
if (attached_console) {
SetWindowPos(GetConsoleWindow(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
FreeConsole();
Expand Down
12 changes: 6 additions & 6 deletions src/rufus.rc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL

IDD_DIALOG DIALOGEX 12, 12, 206, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 1.4.12.535"
CAPTION "Rufus 1.4.12.536"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,291,50,14
Expand Down Expand Up @@ -165,7 +165,7 @@ END
RTL_IDD_DIALOG DIALOGEX 12, 12, 206, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 1.4.12.535"
CAPTION "Rufus 1.4.12.536"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,291,50,14
Expand Down Expand Up @@ -428,8 +428,8 @@ END
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,12,535
PRODUCTVERSION 1,4,12,535
FILEVERSION 1,4,12,536
PRODUCTVERSION 1,4,12,536
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
Expand All @@ -446,13 +446,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.4.12.535"
VALUE "FileVersion", "1.4.12.536"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "� 2011-2014 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.4.12.535"
VALUE "ProductVersion", "1.4.12.536"
END
END
BLOCK "VarFileInfo"
Expand Down
2 changes: 1 addition & 1 deletion src/stdfn.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size)
*buffer = NULL;
}
handle = CreateFileU(path, save?GENERIC_WRITE:GENERIC_READ, FILE_SHARE_READ,
ps, save?CREATE_ALWAYS:OPEN_EXISTING, 0, NULL);
ps, save?CREATE_ALWAYS:OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (handle == INVALID_HANDLE_VALUE) {
uprintf("Could not %s file '%s'\n", save?"create":"open", path);
Expand Down
3 changes: 2 additions & 1 deletion src/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,8 @@ BOOL GetUSBDevices(DWORD devnum)
continue;
}

hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hDrive == INVALID_HANDLE_VALUE) {
uprintf("Could not open '%s': %s\n", devint_detail_data->DevicePath, WindowsErrorString());
continue;
Expand Down
6 changes: 4 additions & 2 deletions src/vhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ BOOL AppendVHDFooter(const char* vhd_path)
size_t i;

PF_INIT(UuidCreate, Rpcrt4);
handle = CreateFileU(vhd_path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
handle = CreateFileU(vhd_path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
li.QuadPart = 0;
if ((handle == INVALID_HANDLE_VALUE) || (!SetFilePointerEx(handle, li, &li, FILE_END))) {
uprintf("Could not open image '%s': %s", vhd_path, WindowsErrorString());
Expand Down Expand Up @@ -220,7 +221,8 @@ BOOL IsHDImage(const char* path)
uint32_t checksum, old_checksum;
LARGE_INTEGER ptr;

handle = CreateFileU(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
handle = CreateFileU(path, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
uprintf("Could not open image '%s'", path);
goto out;
Expand Down

0 comments on commit d46342c

Please sign in to comment.