From 2390b305c82df8ba66196ab174c68d3e3a1df9ff Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 1 Dec 2011 17:54:35 +0000 Subject: [PATCH] [misc] move drive related functions into their own source --- .msvc/rufus_2010.vcxproj | 1 + .msvc/rufus_2010.vcxproj.filters | 61 ++++++------ .msvc/rufus_sources | 1 + Makefile | 2 +- drive.c | 157 +++++++++++++++++++++++++++++++ format.c | 7 +- rufus.c | 131 ++------------------------ rufus.h | 11 +++ rufus.rc | 12 +-- stdio.c | 5 + 10 files changed, 226 insertions(+), 162 deletions(-) create mode 100644 drive.c diff --git a/.msvc/rufus_2010.vcxproj b/.msvc/rufus_2010.vcxproj index 6097ddb6..5438044c 100644 --- a/.msvc/rufus_2010.vcxproj +++ b/.msvc/rufus_2010.vcxproj @@ -147,6 +147,7 @@ + diff --git a/.msvc/rufus_2010.vcxproj.filters b/.msvc/rufus_2010.vcxproj.filters index 2a2450ef..3d76b7ae 100644 --- a/.msvc/rufus_2010.vcxproj.filters +++ b/.msvc/rufus_2010.vcxproj.filters @@ -13,7 +13,7 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav - + {ecff9fec-41c4-4ce8-b725-27ee39754cb7} @@ -48,6 +48,9 @@ Source Files + + Source Files + @@ -66,88 +69,88 @@ Header Files - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc - Header Files\inc + Header Files\ms-sys inc Header Files diff --git a/.msvc/rufus_sources b/.msvc/rufus_sources index b8c41b0a..1932a2ef 100644 --- a/.msvc/rufus_sources +++ b/.msvc/rufus_sources @@ -28,6 +28,7 @@ SOURCES=rufus.c \ stdio.c \ stdlg.c \ msdos.c \ + drive.c \ file.c \ br.c \ fat12.c \ diff --git a/Makefile b/Makefile index 9a30f9b2..9d9c65ef 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # along with this program; if not, see . # -OBJECTS = fat12.o fat16.o fat32.o br.o file.o msdos.o format.o stdio.o stdlg.o rufus.o +OBJECTS = fat12.o fat16.o fat32.o br.o file.o drive.o msdos.o format.o stdio.o stdlg.o rufus.o TARGET = rufus CC = gcc diff --git a/drive.c b/drive.c new file mode 100644 index 00000000..18d425bb --- /dev/null +++ b/drive.c @@ -0,0 +1,157 @@ +/* + * Rufus: The Resourceful USB Formatting Utility + * Drive access function calls + * Copyright (c) 2011 Pete Batard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifdef _CRTDBG_MAP_ALLOC +#include +#include +#endif + +#include +#include +#include +#include + +#include "msapi_utf8.h" +#include "rufus.h" +#include "resource.h" + +/* + * Globals + */ +RUFUS_DRIVE_INFO SelectedDrive; + +/* + * Open a drive or volume with optional write and lock access + * Returns INVALID_HANDLE_VALUE (/!\ which is DIFFERENT from NULL /!\) on failure. + * 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!), + * so we apply the following mitigation factors: + * - 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 + * 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 + */ +HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive) +{ + BOOL r; + DWORD size; + HANDLE hDrive = INVALID_HANDLE_VALUE; + STORAGE_DEVICE_NUMBER_REDEF device_number = {0}; + char drives[26*4]; /* "D:\", "E:\", etc. */ + char *drive = drives; + char logical_drive[] = "\\\\.\\#:"; + char physical_drive[24]; + + if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) { + uprintf("WARNING: Bad index value. Please check the code!\n"); + } + DriveIndex -= DRIVE_INDEX_MIN; + + // If no drive letter is requested, open a phyical drive + if (DriveLetter == NULL) { + safe_sprintf(physical_drive, sizeof(physical_drive), "\\\\.\\PHYSICALDRIVE%d", DriveIndex); + hDrive = CreateFileA(physical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0), + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + if (hDrive == INVALID_HANDLE_VALUE) { + uprintf("Could not open drive %s: %s\n", physical_drive, WindowsErrorString()); + 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; + } + + 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(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); + hDrive = CreateFileA(logical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0), + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + if (hDrive == INVALID_HANDLE_VALUE) { + uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); + continue; + } + + 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:' '; + } + + 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; +} + +/* + * Return the drive letter and volume label + */ +BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label) +{ + HANDLE hDrive; + char DrivePath[] = "#:\\"; + static char volume_label[MAX_PATH+1]; + + *label = STR_NO_LABEL; + + hDrive = GetDriveHandle(DriveIndex, DrivePath, FALSE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + return FALSE; + safe_closehandle(hDrive); + *letter = DrivePath[0]; + + if (GetVolumeInformationA(DrivePath, volume_label, sizeof(volume_label), + NULL, NULL, NULL, NULL, 0) && *volume_label) { + *label = volume_label; + } + + return TRUE; +} diff --git a/format.c b/format.c index cd0fa291..e842ef92 100644 --- a/format.c +++ b/format.c @@ -27,7 +27,7 @@ #include #include #include -// #include +#include #include "msapi_utf8.h" #include "rufus.h" @@ -38,6 +38,11 @@ #include "file.h" #include "format.h" +/* + * Globals + */ +DWORD FormatStatus; + /* * FormatEx callback. Return FALSE to halt operations */ diff --git a/rufus.c b/rufus.c index c4b1f859..a0b67307 100644 --- a/rufus.c +++ b/rufus.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -71,14 +70,9 @@ static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes" HINSTANCE hMainInstance; HWND hMainDialog; char szFolderPath[MAX_PATH]; -HWND hStatus; float fScale = 1.0f; int default_fs; ULONG default_clutersize; -RUFUS_DRIVE_INFO SelectedDrive; -BOOL bBootable; -BOOL bQuickFormat; -DWORD FormatStatus; HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel; static HWND hDeviceTooltip = NULL, hFSTooltip = NULL; @@ -98,124 +92,6 @@ static const char* GetPartitionType(BYTE Type) return "Unknown"; } -/* - * Open a drive with optional write access - returns a drive HANDLE and the drive letter - * or INVALID_HANDLE_VALUE (/!\ which is DIFFERENT from NULL /!\) on failure - * 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!), - * so we apply the following mitigation factors: - * - 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 - * 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 - */ -HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive) -{ - BOOL r; - DWORD size; - HANDLE hDrive = INVALID_HANDLE_VALUE; - STORAGE_DEVICE_NUMBER_REDEF device_number = {0}; - char drives[26*4]; /* "D:\", "E:\", etc. */ - char *drive = drives; - char logical_drive[] = "\\\\.\\#:"; - char physical_drive[24]; - - if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) { - uprintf("WARNING: Bad index value. Please check the code!\n"); - } - DriveIndex -= DRIVE_INDEX_MIN; - - // If no drive letter is requested, open a phyical drive - if (DriveLetter == NULL) { - safe_sprintf(physical_drive, sizeof(physical_drive), "\\\\.\\PHYSICALDRIVE%d", DriveIndex); - hDrive = CreateFileA(physical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0), - FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); - if (hDrive == INVALID_HANDLE_VALUE) { - uprintf("Could not open drive %s: %s\n", physical_drive, WindowsErrorString()); - 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; - } - - 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(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); - hDrive = CreateFileA(logical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0), - FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); - if (hDrive == INVALID_HANDLE_VALUE) { - uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); - continue; - } - - 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:' '; - } - - 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; -} - -/* - * Return the drive letter and volume label - */ -static BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label) -{ - HANDLE hDrive; - char DrivePath[] = "#:\\"; - static char volume_label[MAX_PATH+1]; - - *label = STR_NO_LABEL; - - hDrive = GetDriveHandle(DriveIndex, DrivePath, FALSE, FALSE); - if (hDrive == INVALID_HANDLE_VALUE) - return FALSE; - safe_closehandle(hDrive); - *letter = DrivePath[0]; - - if (GetVolumeInformationA(DrivePath, volume_label, sizeof(volume_label), NULL, NULL, NULL, NULL, 0) && *volume_label) { - *label = volume_label; - } - - return TRUE; -} #define KB 1024LL #define MB 1048576LL @@ -316,6 +192,9 @@ out: #undef GB #undef TB +/* + * Populate the Allocation unit size field + */ static BOOL SetClusterSizes(int FSType) { char szDefault[64]; @@ -689,7 +568,9 @@ static BOOL GetUSBDevices(void) return TRUE; } -/* Toggle controls according to operation */ +/* + * Toggle controls according to operation + */ static void EnableControls(BOOL bEnable) { EnableWindow(GetDlgItem(hMainDialog, IDC_DEVICE), bEnable); diff --git a/rufus.h b/rufus.h index 970927a8..d4cd9509 100644 --- a/rufus.h +++ b/rufus.h @@ -136,6 +136,7 @@ extern BOOL ExtractMSDOS(const char* path); extern void __cdecl FormatThread(void* param); extern BOOL CreatePartition(HANDLE hDrive); extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive); +extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); __inline static BOOL UnlockDrive(HANDLE hDrive) { @@ -155,6 +156,16 @@ extern void StrArrayAdd(StrArray* arr, const char* str); extern void StrArrayClear(StrArray* arr); extern void StrArrayDestroy(StrArray* arr); +/* Clang/MinGW32 has an issue with intptr_t */ +#ifndef _UINTPTR_T_DEFINED +#define _UINTPTR_T_DEFINED +#ifdef _WIN64 + typedef unsigned __int64 uintptr_t; +#else + typedef unsigned int uintptr_t; +#endif +#endif + /* We need a redef of this MS structure */ typedef struct { DWORD DeviceType; diff --git a/rufus.rc b/rufus.rc index 3790baf5..732d6845 100644 --- a/rufus.rc +++ b/rufus.rc @@ -63,7 +63,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP CONTROL "https://github.com/pbatard/rufus",IDC_ABOUT_RUFUS_URL, "SysLink",WS_TABSTOP,46,47,114,9 - LTEXT "Version 1.0.0 (Build 58)",IDC_STATIC,46,19,78,8 + LTEXT "Version 1.0.0 (Build 59)",IDC_STATIC,46,19,78,8 PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 @@ -162,8 +162,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,58 - PRODUCTVERSION 1,0,0,58 + FILEVERSION 1,0,0,59 + PRODUCTVERSION 1,0,0,59 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -180,13 +180,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.0.0.58" + VALUE "FileVersion", "1.0.0.59" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.0.0.58" + VALUE "ProductVersion", "1.0.0.59" END END BLOCK "VarFileInfo" @@ -212,7 +212,7 @@ IDI_ICON ICON "rufus.ico" STRINGTABLE BEGIN - IDS_VERSION "Rufus v1.0.0.58" + IDS_VERSION "Rufus v1.0.0.59" END #endif // English resources diff --git a/stdio.c b/stdio.c index b28f621b..b253ca1c 100644 --- a/stdio.c +++ b/stdio.c @@ -31,6 +31,11 @@ #include "rufus.h" #include "resource.h" +/* + * Globals + */ +HWND hStatus; + #ifdef RUFUS_DEBUG void _uprintf(const char *format, ...) {