"Fossies" - the Fresh Open Source Software Archive

Member "rufus-3.13/src/rufus.h" (20 Nov 2020, 30832 Bytes) of package /linux/misc/rufus-3.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rufus.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.12_vs_3.13.

    1 /*
    2  * Rufus: The Reliable USB Formatting Utility
    3  * Copyright © 2011-2020 Pete Batard <pete@akeo.ie>
    4  *
    5  * This program is free software: you can redistribute it and/or modify
    6  * it under the terms of the GNU General Public License as published by
    7  * the Free Software Foundation, either version 3 of the License, or
    8  * (at your option) any later version.
    9  *
   10  * This program is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  * GNU General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   17  */
   18 #include <windows.h>
   19 #include <malloc.h>
   20 #include <inttypes.h>
   21 
   22 #if defined(_MSC_VER)
   23 // Disable some VS Code Analysis warnings
   24 #pragma warning(disable: 4996)      // Ignore deprecated
   25 #pragma warning(disable: 6258)      // I know what I'm using TerminateThread for
   26 #pragma warning(disable: 26451)     // Stop bugging me with casts already!
   27 #pragma warning(disable: 28159)     // I'll keep using GetVersionEx(), thank you very much...
   28 #endif
   29 
   30 #pragma once
   31 
   32 /*
   33  * Features not ready for prime time and that may *DESTROY* your data - USE AT YOUR OWN RISKS!
   34  */
   35 //#define RUFUS_TEST
   36 
   37 #define APPLICATION_NAME            "Rufus"
   38 #if defined(_M_AMD64)
   39 #define APPLICATION_ARCH            "x64"
   40 #elif defined(_M_IX86)
   41 #define APPLICATION_ARCH            "x86"
   42 #elif defined(_M_ARM64)
   43 #define APPLICATION_ARCH            "Arm64"
   44 #elif defined(_M_ARM)
   45 #define APPLICATION_ARCH            "Arm"
   46 #else
   47 #define APPLICATION_ARCH            "(Unknown Arch)"
   48 #endif
   49 #define COMPANY_NAME                "Akeo Consulting"
   50 #define STR_NO_LABEL                "NO_LABEL"
   51 // Yes, there exist characters between these seemingly empty quotes!
   52 #define LEFT_TO_RIGHT_MARK          "‎"
   53 #define RIGHT_TO_LEFT_MARK          "‏"
   54 #define LEFT_TO_RIGHT_EMBEDDING     "‪"
   55 #define RIGHT_TO_LEFT_EMBEDDING     "‫"
   56 #define POP_DIRECTIONAL_FORMATTING  "‬"
   57 #define LEFT_TO_RIGHT_OVERRIDE      "‭"
   58 #define RIGHT_TO_LEFT_OVERRIDE      "‮"
   59 #define DRIVE_ACCESS_TIMEOUT        15000       // How long we should retry drive access (in ms)
   60 #define DRIVE_ACCESS_RETRIES        150         // How many times we should retry
   61 #define DRIVE_INDEX_MIN             0x00000080
   62 #define DRIVE_INDEX_MAX             0x000000C0
   63 #define MIN_DRIVE_SIZE              8           // Minimum size a drive must have, to be formattable (in MB)
   64 #define MIN_EXTRA_PART_SIZE         (1024*1024) // Minimum size of the extra partition, in bytes
   65 #define MIN_EXT_SIZE                (256*1024*1024) // Minimum size we allow for ext formatting
   66 #define MAX_ARCHS                   9           // Number of arhitectures we recognize
   67 #define MAX_DRIVES                  (DRIVE_INDEX_MAX - DRIVE_INDEX_MIN)
   68 #define MAX_TOOLTIPS                128
   69 #define MAX_SIZE_SUFFIXES           6           // bytes, KB, MB, GB, TB, PB
   70 #define MAX_CLUSTER_SIZES           18
   71 #define MAX_PROGRESS                0xFFFF
   72 #define MAX_LOG_SIZE                0x7FFFFFFE
   73 #define MAX_REFRESH                 25          // How long we should wait to refresh UI elements (in ms)
   74 #define MAX_GUID_STRING_LENGTH      40
   75 #define MAX_PARTITIONS              16          // Maximum number of partitions we handle
   76 #define MAX_ESP_TOGGLE              8           // Maximum number of entries we record to toggle GPT ESP back and forth
   77 #define MAX_ISO_TO_ESP_SIZE         512         // Maximum size we allow for the ISO → ESP option (in MB)
   78 #define MAX_SECTORS_TO_CLEAR        128         // nb sectors to zap when clearing the MBR/GPT (must be >34)
   79 #define MAX_WININST                 4           // Max number of install[.wim|.esd] we can handle on an image
   80 #define MBR_UEFI_MARKER             0x49464555  // 'U', 'E', 'F', 'I', as a 32 bit little endian longword
   81 #define MORE_INFO_URL               0xFFFF
   82 #define STATUS_MSG_TIMEOUT          3500        // How long should cheat mode messages appear for on the status bar
   83 #define WRITE_RETRIES               4
   84 #define WRITE_TIMEOUT               5000        // How long we should wait between write retries (in ms)
   85 #if defined(_DEBUG)
   86 #define SEARCH_PROCESS_TIMEOUT      60000
   87 #else
   88 #define SEARCH_PROCESS_TIMEOUT      10000       // How long we should search for conflicting processes before giving up (in ms)
   89 #endif
   90 #define NET_SESSION_TIMEOUT         3500        // How long we should wait to connect, send or receive internet data
   91 #define MARQUEE_TIMER_REFRESH       10          // Time between progress bar marquee refreshes, in ms
   92 #define FS_DEFAULT                  FS_FAT32
   93 #define SINGLE_CLUSTERSIZE_DEFAULT  0x00000100
   94 #define BADLOCKS_PATTERN_TYPES      5
   95 #define BADBLOCK_PATTERN_COUNT      4
   96 #define BADBLOCK_PATTERN_ONE_PASS   {0x55, 0x00, 0x00, 0x00}
   97 #define BADBLOCK_PATTERN_TWO_PASSES {0x55, 0xaa, 0x00, 0x00}
   98 #define BADBLOCK_PATTERN_SLC        {0x00, 0xff, 0x55, 0xaa}
   99 #define BADCLOCK_PATTERN_MLC        {0x00, 0xff, 0x33, 0xcc}
  100 #define BADBLOCK_PATTERN_TLC        {0x00, 0xff, 0x1c71c7, 0xe38e38}
  101 #define BADBLOCK_BLOCK_SIZE         (128 * 1024)
  102 #define LARGE_FAT32_SIZE            (32*1073741824LL)   // Size at which we need to use fat32format
  103 #define UDF_FORMAT_SPEED            3.1f        // Speed estimate at which we expect UDF drives to be formatted (GB/s)
  104 #define UDF_FORMAT_WARN             20          // Duration (in seconds) above which we warn about long UDF formatting times
  105 #define MAX_FAT32_SIZE              2.0f        // Threshold above which we disable FAT32 formatting (in TB)
  106 #define FAT32_CLUSTER_THRESHOLD     1.011f      // For FAT32, cluster size changes don't occur at power of 2 boundaries but sligthly above
  107 #define DD_BUFFER_SIZE              65536       // Minimum size of the buffer we use for DD operations
  108 #define UBUFFER_SIZE                4096
  109 #define RSA_SIGNATURE_SIZE          256
  110 #define CBN_SELCHANGE_INTERNAL      (CBN_SELCHANGE + 256)
  111 #if defined(RUFUS_TEST)
  112 #define RUFUS_URL                   "http://nano/~rufus"
  113 #else
  114 #define RUFUS_URL                   "https://rufus.ie"
  115 #endif
  116 #define DOWNLOAD_URL                RUFUS_URL "/downloads"
  117 #define FILES_URL                   RUFUS_URL "/files"
  118 #define FIDO_VERSION                "z1"
  119 #define SECURE_BOOT_MORE_INFO_URL   "https://github.com/pbatard/rufus/wiki/FAQ#Why_do_I_need_to_disable_Secure_Boot_to_use_UEFINTFS"
  120 #define WPPRECORDER_MORE_INFO_URL   "https://github.com/pbatard/rufus/wiki/FAQ#BSODs_with_Windows_To_Go_drives_created_from_Windows_10_1809_ISOs"
  121 #define SEVENZIP_URL                "https://www.7-zip.org"
  122 #define FILES_DIR                   "rufus_files"
  123 #define DEFAULT_ESP_MOUNT_POINT     "S:\\"
  124 #define IS_POWER_OF_2(x)            ((x != 0) && (((x) & ((x) - 1)) == 0))
  125 #define IGNORE_RETVAL(expr)         do { (void)(expr); } while(0)
  126 #ifndef ARRAYSIZE
  127 #define ARRAYSIZE(A)                (sizeof(A)/sizeof((A)[0]))
  128 #endif
  129 #ifndef STRINGIFY
  130 #define STRINGIFY(x)                #x
  131 #endif
  132 #define IsChecked(CheckBox_ID)      (IsDlgButtonChecked(hMainDialog, CheckBox_ID) == BST_CHECKED)
  133 #define MB_IS_RTL                   (right_to_left_mode?MB_RTLREADING|MB_RIGHT:0)
  134 #define CHECK_FOR_USER_CANCEL       if (IS_ERROR(FormatStatus) && (SCODE_CODE(FormatStatus) == ERROR_CANCELLED)) goto out
  135 // Bit masks used for the display of additional image options in the UI
  136 #define IMOP_WINTOGO                0x01
  137 #define IMOP_PERSISTENCE            0x02
  138 
  139 #define ComboBox_GetCurItemData(hCtrl) ComboBox_GetItemData(hCtrl, ComboBox_GetCurSel(hCtrl))
  140 
  141 #define safe_free(p) do {free((void*)p); p = NULL;} while(0)
  142 #define safe_mm_free(p) do {_mm_free((void*)p); p = NULL;} while(0)
  143 #define safe_min(a, b) min((size_t)(a), (size_t)(b))
  144 #define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
  145     ((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
  146 #define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
  147 #define static_strcpy(dst, src) safe_strcpy(dst, sizeof(dst), src)
  148 #define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
  149 #define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
  150 #define static_strcat(dst, src) safe_strcat(dst, sizeof(dst), src)
  151 #define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
  152 #define safe_strstr(str1, str2) strstr(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
  153 #define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
  154 #define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
  155 #define safe_strnicmp(str1, str2, count) _strnicmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
  156 #define safe_closehandle(h) do {if ((h != INVALID_HANDLE_VALUE) && (h != NULL)) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
  157 #define safe_release_dc(hDlg, hDC) do {if ((hDC != INVALID_HANDLE_VALUE) && (hDC != NULL)) {ReleaseDC(hDlg, hDC); hDC = NULL;}} while(0)
  158 #define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0)
  159 #define static_sprintf(dst, ...) safe_sprintf(dst, sizeof(dst), __VA_ARGS__)
  160 #define safe_strlen(str) ((((char*)str)==NULL)?0:strlen(str))
  161 #define safe_strdup _strdup
  162 #if defined(_MSC_VER)
  163 #define safe_vsnprintf(buf, size, format, arg) _vsnprintf_s(buf, size, _TRUNCATE, format, arg)
  164 #else
  165 #define safe_vsnprintf vsnprintf
  166 #endif
  167 
  168 extern void _uprintf(const char *format, ...);
  169 extern void _uprintfs(const char *str);
  170 #define uprintf(...) _uprintf(__VA_ARGS__)
  171 #define uprintfs(s) _uprintfs(s)
  172 #define vuprintf(...) do { if (verbose) _uprintf(__VA_ARGS__); } while(0)
  173 #define vvuprintf(...) do { if (verbose > 1) _uprintf(__VA_ARGS__); } while(0)
  174 #define suprintf(...) do { if (!bSilent) _uprintf(__VA_ARGS__); } while(0)
  175 #define uuprintf(...) do { if (usb_debug) _uprintf(__VA_ARGS__); } while(0)
  176 #define ubprintf(...) do { safe_sprintf(&ubuffer[ubuffer_pos], UBUFFER_SIZE - ubuffer_pos - 2, __VA_ARGS__); \
  177     ubuffer_pos = strlen(ubuffer); ubuffer[ubuffer_pos++] = '\r'; ubuffer[ubuffer_pos++] = '\n'; \
  178     ubuffer[ubuffer_pos] = 0; } while(0)
  179 #define ubflush() do { if (ubuffer_pos) uprintf("%s", ubuffer); ubuffer_pos = 0; } while(0)
  180 #ifdef _DEBUG
  181 #define duprintf(...) _uprintf(__VA_ARGS__)
  182 #else
  183 #define duprintf(...)
  184 #endif
  185 
  186 /* Custom Windows messages */
  187 enum user_message_type {
  188     UM_FORMAT_COMPLETED = WM_APP,
  189     UM_MEDIA_CHANGE,
  190     UM_PROGRESS_INIT,
  191     UM_PROGRESS_EXIT,
  192     UM_NO_UPDATE,
  193     UM_UPDATE_CSM_TOOLTIP,
  194     UM_RESIZE_BUTTONS,
  195     UM_ENABLE_CONTROLS,
  196     UM_SELECT_ISO,
  197     UM_TIMER_START,
  198     UM_FORMAT_START,
  199     // Start of the WM IDs for the language menu items
  200     UM_LANGUAGE_MENU = WM_APP + 0x100
  201 };
  202 
  203 /* Custom notifications */
  204 enum notification_type {
  205     MSG_INFO,
  206     MSG_WARNING,
  207     MSG_ERROR,
  208     MSG_QUESTION,
  209     MSG_WARNING_QUESTION
  210 };
  211 typedef INT_PTR (CALLBACK *Callback_t)(HWND, UINT, WPARAM, LPARAM);
  212 typedef struct {
  213     WORD id;
  214     union {
  215         Callback_t callback;
  216         char* url;
  217     };
  218 } notification_info;    // To provide a "More info..." on notifications
  219 
  220 /* Status Bar sections */
  221 #define SB_SECTION_LEFT         0
  222 #define SB_SECTION_RIGHT        1
  223 #define SB_TIMER_SECTION_SIZE   58.0f
  224 
  225 /* Timers used throughout the program */
  226 enum timer_type {
  227     TID_MESSAGE_INFO = 0x1000,
  228     TID_MESSAGE_STATUS,
  229     TID_OUTPUT_INFO,
  230     TID_OUTPUT_STATUS,
  231     TID_BADBLOCKS_UPDATE,
  232     TID_APP_TIMER,
  233     TID_BLOCKING_TIMER,
  234     TID_REFRESH_TIMER,
  235     TID_MARQUEE_TIMER
  236 };
  237 
  238 /* Action type, for progress bar breakdown */
  239 enum action_type {
  240     OP_NOOP_WITH_TASKBAR = -3,
  241     OP_NOOP = -2,
  242     OP_INIT = -1,
  243     OP_ANALYZE_MBR = 0,
  244     OP_BADBLOCKS,
  245     OP_ZERO_MBR,
  246     OP_PARTITION,
  247     OP_FORMAT,
  248     OP_CREATE_FS,
  249     OP_FIX_MBR,
  250     OP_FILE_COPY,
  251     OP_FINALIZE,
  252     OP_MAX
  253 };
  254 
  255 /* File system indexes in our FS combobox */
  256 enum fs_type {
  257     FS_UNKNOWN = -1,
  258     FS_FAT16 = 0,
  259     FS_FAT32,
  260     FS_NTFS,
  261     FS_UDF,
  262     FS_EXFAT,
  263     FS_REFS,
  264     FS_EXT2,
  265     FS_EXT3,
  266     FS_EXT4,
  267     FS_MAX
  268 };
  269 
  270 enum boot_type {
  271     BT_NON_BOOTABLE = 0,
  272     BT_MSDOS,
  273     BT_FREEDOS,
  274     BT_IMAGE,
  275     BT_SYSLINUX_V4,     // Start of indexes that only display in advanced mode
  276     BT_SYSLINUX_V6,
  277     BT_REACTOS,
  278     BT_GRUB4DOS,
  279     BT_GRUB2,
  280     BT_UEFI_NTFS,
  281     BT_MAX
  282 };
  283 
  284 enum target_type {
  285     TT_BIOS = 0,
  286     TT_UEFI,
  287     TT_MAX
  288 };
  289 // For the partition types we'll use Microsoft's PARTITION_STYLE_### constants
  290 #define PARTITION_STYLE_SFD PARTITION_STYLE_RAW
  291 
  292 enum checksum_type {
  293     CHECKSUM_MD5 = 0,
  294     CHECKSUM_SHA1,
  295     CHECKSUM_SHA256,
  296     CHECKSUM_SHA512,
  297     CHECKSUM_MAX
  298 };
  299 
  300 /* Special handling for old .c32 files we need to replace */
  301 #define NB_OLD_C32          2
  302 #define OLD_C32_NAMES       { "menu.c32", "vesamenu.c32" }
  303 #define OLD_C32_THRESHOLD   { 53500, 148000 }
  304 
  305 /* ISO details that the application may want */
  306 #define WINPE_I386          0x0007
  307 #define WINPE_AMD64         0x0023
  308 #define WINPE_MININT        0x01C0
  309 #define SPECIAL_WIM_VERSION 0x000E0000
  310 #define HAS_KOLIBRIOS(r)    (r.has_kolibrios)
  311 #define HAS_REACTOS(r)      (r.reactos_path[0] != 0)
  312 #define HAS_GRUB(r)         ((r.has_grub2) || (r.has_grub4dos))
  313 #define HAS_SYSLINUX(r)     (r.sl_version != 0)
  314 #define HAS_BOOTMGR_BIOS(r) (r.has_bootmgr)
  315 #define HAS_BOOTMGR_EFI(r)  (r.has_bootmgr_efi)
  316 #define HAS_BOOTMGR(r)      (HAS_BOOTMGR_BIOS(r) || HAS_BOOTMGR_EFI(r))
  317 #define HAS_REGULAR_EFI(r)  (r.has_efi & 0x7FFE)
  318 #define HAS_WININST(r)      (r.wininst_index != 0)
  319 #define HAS_WINPE(r)        (((r.winpe & WINPE_I386) == WINPE_I386)||((r.winpe & WINPE_AMD64) == WINPE_AMD64)||((r.winpe & WINPE_MININT) == WINPE_MININT))
  320 #define HAS_WINDOWS(r)      (HAS_BOOTMGR(r) || (r.uses_minint) || HAS_WINPE(r))
  321 #define HAS_WIN7_EFI(r)     ((r.has_efi == 1) && HAS_WININST(r))
  322 #define HAS_EFI_IMG(r)      (r.efi_img_path[0] != 0)
  323 #define IS_DD_BOOTABLE(r)   (r.is_bootable_img)
  324 #define IS_DD_ONLY(r)       (r.is_bootable_img && (!r.is_iso || r.disable_iso))
  325 #define IS_EFI_BOOTABLE(r)  (r.has_efi != 0)
  326 #define IS_BIOS_BOOTABLE(r) (HAS_BOOTMGR(r) || HAS_SYSLINUX(r) || HAS_WINPE(r) || HAS_GRUB(r) || HAS_REACTOS(r) || HAS_KOLIBRIOS(r))
  327 #define HAS_WINTOGO(r)      (HAS_BOOTMGR(r) && IS_EFI_BOOTABLE(r) && HAS_WININST(r))
  328 #define HAS_PERSISTENCE(r)  ((HAS_SYSLINUX(r) || HAS_GRUB(r)) && !(HAS_WINDOWS(r) || HAS_REACTOS(r) || HAS_KOLIBRIOS(r)))
  329 #define IS_FAT(fs)          ((fs_type == FS_FAT16) || (fs_type == FS_FAT32))
  330 #define SYMLINKS_RR         0x01
  331 #define SYMLINKS_UDF        0x02
  332 
  333 typedef struct {
  334     char label[192];                    // 3*64 to account for UTF-8
  335     char usb_label[192];                // converted USB label for workaround
  336     char cfg_path[128];                 // path to the ISO's isolinux.cfg
  337     char reactos_path[128];             // path to the ISO's freeldr.sys or setupldr.sys
  338     char wininst_path[MAX_WININST][64]; // path to the Windows install image(s)
  339     char efi_img_path[128];             // path to an efi.img file
  340     uint64_t image_size;
  341     uint64_t archive_size;
  342     uint64_t projected_size;
  343     int64_t mismatch_size;
  344     uint32_t wininst_version;
  345     BOOLEAN is_iso;
  346     uint8_t is_bootable_img;
  347     BOOLEAN is_vhd;
  348     BOOLEAN is_windows_img;
  349     BOOLEAN disable_iso;
  350     uint16_t winpe;
  351     uint16_t has_efi;
  352     uint8_t has_md5sum;
  353     uint8_t wininst_index;
  354     uint8_t has_symlinks;
  355     BOOLEAN has_4GB_file;
  356     BOOLEAN has_long_filename;
  357     BOOLEAN has_deep_directories;
  358     BOOLEAN has_bootmgr;
  359     BOOLEAN has_bootmgr_efi;
  360     BOOLEAN has_autorun;
  361     BOOLEAN has_old_c32[NB_OLD_C32];
  362     BOOLEAN has_old_vesamenu;
  363     BOOLEAN has_efi_syslinux;
  364     BOOLEAN needs_syslinux_overwrite;
  365     BOOLEAN has_grub4dos;
  366     BOOLEAN has_grub2;
  367     BOOLEAN has_kolibrios;
  368     BOOLEAN uses_casper;
  369     BOOLEAN uses_minint;
  370     BOOLEAN compression_type;
  371     uint16_t sl_version;    // Syslinux/Isolinux version
  372     char sl_version_str[12];
  373     char sl_version_ext[32];
  374     char grub2_version[32];
  375 } RUFUS_IMG_REPORT;
  376 
  377 /* Isolate the Syslinux version numbers */
  378 #define SL_MAJOR(x) ((uint8_t)((x)>>8))
  379 #define SL_MINOR(x) ((uint8_t)(x))
  380 
  381 typedef struct {
  382     uint16_t version[3];
  383     uint32_t platform_min[2];       // minimum platform version required
  384     char* download_url;
  385     char* release_notes;
  386 } RUFUS_UPDATE;
  387 
  388 #define IMG_SAVE_TYPE_VHD 1
  389 #define IMG_SAVE_TYPE_ISO 2
  390 
  391 typedef struct {
  392     DWORD Type;
  393     DWORD DeviceNum;
  394     DWORD BufSize;
  395     LONGLONG DeviceSize;
  396     char* DevicePath;
  397     char* ImagePath;
  398     char* Label;
  399 } IMG_SAVE;
  400 
  401 /*
  402  * Structure and macros used for the extensions specification of FileDialog()
  403  * You can use:
  404  *   EXT_DECL(my_extensions, "default.std", __VA_GROUP__("*.std", "*.other"), __VA_GROUP__("Standard type", "Other Type"));
  405  * to define an 'ext_t my_extensions' variable initialized with the relevant attributes.
  406  */
  407 typedef struct ext_t {
  408     const size_t count;
  409     const char* filename;
  410     const char** extension;
  411     const char** description;
  412 } ext_t;
  413 
  414 #ifndef __VA_GROUP__
  415 #define __VA_GROUP__(...)  __VA_ARGS__
  416 #endif
  417 #define EXT_X(prefix, ...) const char* _##prefix##_x[] = { __VA_ARGS__ }
  418 #define EXT_D(prefix, ...) const char* _##prefix##_d[] = { __VA_ARGS__ }
  419 #define EXT_DECL(var, filename, extensions, descriptions)                   \
  420     EXT_X(var, extensions);                                                 \
  421     EXT_D(var, descriptions);                                               \
  422     ext_t var = { ARRAYSIZE(_##var##_x), filename, _##var##_x, _##var##_d }
  423 
  424 /* Duplication of the TBPFLAG enum for Windows 7 taskbar progress */
  425 typedef enum TASKBAR_PROGRESS_FLAGS
  426 {
  427     TASKBAR_NOPROGRESS = 0,
  428     TASKBAR_INDETERMINATE = 0x1,
  429     TASKBAR_NORMAL = 0x2,
  430     TASKBAR_ERROR = 0x4,
  431     TASKBAR_PAUSED = 0x8
  432 } TASKBAR_PROGRESS_FLAGS;
  433 
  434 /* Windows versions */
  435 enum WindowsVersion {
  436     WINDOWS_UNDEFINED = -1,
  437     WINDOWS_UNSUPPORTED = 0,
  438     WINDOWS_XP = 0x51,
  439     WINDOWS_2003 = 0x52,    // Also XP_64
  440     WINDOWS_VISTA = 0x60,   // Also 2008
  441     WINDOWS_7 = 0x61,       // Also 2008_R2
  442     WINDOWS_8 = 0x62,       // Also 2012
  443     WINDOWS_8_1 = 0x63,     // Also 2012_R2
  444     WINDOWS_10_PREVIEW1 = 0x64,
  445     WINDOWS_10 = 0xA0,
  446     WINDOWS_MAX
  447 };
  448 
  449 enum CpuArch {
  450     CPU_ARCH_X86_32 = 0,
  451     CPU_ARCH_X86_64,
  452     CPU_ARCH_ARM_32,
  453     CPU_ARCH_ARM_64,
  454     CPU_ARCH_UNDEFINED,
  455     CPU_ARCH_MAX
  456 };
  457 
  458 /*
  459  * Globals
  460  */
  461 extern RUFUS_UPDATE update;
  462 extern RUFUS_IMG_REPORT img_report;
  463 extern HINSTANCE hMainInstance;
  464 extern HWND hMainDialog, hLogDialog, hStatus, hDeviceList, hCapacity, hImageOption;
  465 extern HWND hPartitionScheme, hTargetSystem, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog;
  466 extern HWND hInfo, hProgress, hDiskID;
  467 extern WORD selected_langid;
  468 extern DWORD FormatStatus, DownloadStatus, MainThreadId, LastWriteError;
  469 extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, op_in_progress, right_to_left_mode;
  470 extern BOOL allow_dual_uefi_bios, large_drive, usb_debug;
  471 extern int64_t iso_blocking_status;
  472 extern uint8_t image_options;
  473 extern uint16_t rufus_version[3], embedded_sl_version[2];
  474 extern uint64_t persistence_size;
  475 extern size_t ubuffer_pos;
  476 extern const int nb_steps[FS_MAX];
  477 extern float fScale;
  478 extern int nWindowsVersion, nWindowsBuildNumber, dialog_showing, force_update;
  479 extern int fs_type, boot_type, partition_type, target_type;
  480 extern unsigned long syslinux_ldlinux_len[2];
  481 extern char WindowsVersionStr[128], ubuffer[UBUFFER_SIZE], embedded_sl_version_str[2][12];
  482 extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH], temp_dir[MAX_PATH], system_dir[MAX_PATH], sysnative_dir[MAX_PATH];
  483 extern char *image_path, *fido_url;
  484 
  485 /*
  486  * Shared prototypes
  487  */
  488 extern void GetWindowsVersion(void);
  489 extern BOOL is_x64(void);
  490 extern BOOL GetCpuArch(void);
  491 extern const char *WindowsErrorString(void);
  492 extern void DumpBufferHex(void *buf, size_t size);
  493 extern void PrintStatusInfo(BOOL info, BOOL debug, unsigned int duration, int msg_id, ...);
  494 #define PrintStatus(...) PrintStatusInfo(FALSE, FALSE, __VA_ARGS__)
  495 #define PrintStatusDebug(...) PrintStatusInfo(FALSE, TRUE, __VA_ARGS__)
  496 #define PrintInfo(...) PrintStatusInfo(TRUE, FALSE, __VA_ARGS__)
  497 #define PrintInfoDebug(...) PrintStatusInfo(TRUE, TRUE, __VA_ARGS__)
  498 extern void UpdateProgress(int op, float percent);
  499 extern void UpdateProgressWithInfo(int op, int msg, uint64_t processed, uint64_t total);
  500 #define UpdateProgressWithInfoInit(hProgressDialog, bNoAltMode) UpdateProgressWithInfo(OP_INIT, (int)bNoAltMode, (uint64_t)(uintptr_t)hProgressDialog, 0);
  501 extern const char* StrError(DWORD error_code, BOOL use_default_locale);
  502 extern char* GuidToString(const GUID* guid);
  503 extern GUID* StringToGuid(const char* str);
  504 extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units);
  505 extern char* TimestampToHumanReadable(uint64_t ts);
  506 extern HWND MyCreateDialog(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc);
  507 extern INT_PTR MyDialogBox(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc);
  508 extern void CenterDialog(HWND hDlg, HWND hParent);
  509 extern void ResizeMoveCtrl(HWND hDlg, HWND hCtrl, int dx, int dy, int dw, int dh, float scale);
  510 extern void ResizeButtonHeight(HWND hDlg, int id);
  511 extern void CreateStatusBar(void);
  512 extern void CreateStaticFont(HDC hDC, HFONT* hFont, BOOL underlined);
  513 extern void SetTitleBarIcon(HWND hDlg);
  514 extern BOOL CreateTaskbarList(void);
  515 extern BOOL SetTaskbarProgressState(TASKBAR_PROGRESS_FLAGS tbpFlags);
  516 extern BOOL SetTaskbarProgressValue(ULONGLONG ullCompleted, ULONGLONG ullTotal);
  517 extern INT_PTR CreateAboutBox(void);
  518 extern BOOL CreateTooltip(HWND hControl, const char* message, int duration);
  519 extern void DestroyTooltip(HWND hWnd);
  520 extern void DestroyAllTooltips(void);
  521 extern BOOL Notification(int type, const char* dont_display_setting, const notification_info* more_info, char* title, char* format, ...);
  522 extern int SelectionDialog(char* title, char* message, char** choices, int size);
  523 extern void ListDialog(char* title, char* message, char** items, int size);
  524 extern SIZE GetTextSize(HWND hCtrl, char* txt);
  525 extern BOOL ExtractAppIcon(const char* filename, BOOL bSilent);
  526 extern BOOL ExtractDOS(const char* path);
  527 extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan);
  528 extern int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes);
  529 extern BOOL HasEfiImgBootLoaders(void);
  530 extern BOOL DumpFatDir(const char* path, int32_t cluster);
  531 extern char* MountISO(const char* path);
  532 extern void UnMountISO(void);
  533 extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs);
  534 extern uint16_t GetSyslinuxVersion(char* buf, size_t buf_size, char** ext);
  535 extern BOOL SetAutorun(const char* path);
  536 extern char* FileDialog(BOOL save, char* path, const ext_t* ext, DWORD options);
  537 extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
  538 extern unsigned char* GetResource(HMODULE module, char* name, char* type, const char* desc, DWORD* len, BOOL duplicate);
  539 extern DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc);
  540 extern DWORD RunCommand(const char* cmdline, const char* dir, BOOL log);
  541 extern BOOL CompareGUID(const GUID *guid1, const GUID *guid2);
  542 extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
  543 extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
  544 extern uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress);
  545 extern DWORD DownloadSignedFile(const char* url, const char* file, HWND hProgressDialog, BOOL PromptOnError);
  546 extern HANDLE DownloadSignedFileThreaded(const char* url, const char* file, HWND hProgressDialog, BOOL bPromptOnError);
  547 extern INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  548 extern BOOL SetUpdateCheck(void);
  549 extern BOOL CheckForUpdates(BOOL force);
  550 extern void DownloadNewVersion(void);
  551 extern BOOL DownloadISO(void);
  552 extern BOOL IsDownloadable(const char* url);
  553 extern BOOL IsShown(HWND hDlg);
  554 extern uint32_t read_file(const char* path, uint8_t** buf);
  555 extern uint32_t write_file(const char* path, const uint8_t* buf, const uint32_t size);
  556 extern char* get_token_data_file_indexed(const char* token, const char* filename, int index);
  557 #define get_token_data_file(token, filename) get_token_data_file_indexed(token, filename, 1)
  558 extern char* set_token_data_file(const char* token, const char* data, const char* filename);
  559 extern char* get_token_data_buffer(const char* token, unsigned int n, const char* buffer, size_t buffer_size);
  560 extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix);
  561 extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix);
  562 extern char* replace_char(const char* src, const char c, const char* rep);
  563 extern void parse_update(char* buf, size_t len);
  564 extern void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str, uint8_t asn1_type, size_t* data_len);
  565 extern uint8_t WimExtractCheck(BOOL bSilent);
  566 extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst, BOOL bSilent);
  567 extern BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst, BOOL bSilent);
  568 extern BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst, BOOL bSilent);
  569 extern BOOL WimApplyImage(const char* image, int index, const char* dst);
  570 extern uint8_t IsBootableImage(const char* path);
  571 extern BOOL AppendVHDFooter(const char* vhd_path);
  572 extern int SetWinToGoIndex(void);
  573 extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid);
  574 extern char* GetSignatureName(const char* path, const char* country_code);
  575 extern uint64_t GetSignatureTimeStamp(const char* path);
  576 extern LONG ValidateSignature(HWND hDlg, const char* path);
  577 extern BOOL ValidateOpensslSignature(BYTE* pbBuffer, DWORD dwBufferLen, BYTE* pbSignature, DWORD dwSigLen);
  578 extern BOOL IsFontAvailable(const char* font_name);
  579 extern BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
  580     LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries);
  581 extern BOOL SetThreadAffinity(DWORD_PTR* thread_affinity, size_t num_threads);
  582 extern BOOL HashFile(const unsigned type, const char* path, uint8_t* sum);
  583 extern BOOL HashBuffer(const unsigned type, const unsigned char* buf, const size_t len, uint8_t* sum);
  584 extern BOOL IsFileInDB(const char* path);
  585 extern BOOL IsBufferInDB(const unsigned char* buf, const size_t len);
  586 #define printbits(x) _printbits(sizeof(x), &x, 0)
  587 #define printbitslz(x) _printbits(sizeof(x), &x, 1)
  588 extern char* _printbits(size_t const size, void const * const ptr, int leading_zeroes);
  589 extern BOOL IsCurrentProcessElevated(void);
  590 extern char* GetCurrentMUI(void);
  591 extern void SetAlertPromptMessages(void);
  592 extern BOOL SetAlertPromptHook(void);
  593 extern void ClrAlertPromptHook(void);
  594 extern DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt);
  595 extern BYTE SearchProcess(char* HandleName, DWORD dwTimeout, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet);
  596 extern BOOL EnablePrivileges(void);
  597 extern void FlashTaskbar(HANDLE handle);
  598 extern DWORD WaitForSingleObjectWithMessages(HANDLE hHandle, DWORD dwMilliseconds);
  599 extern HICON CreateMirroredIcon(HICON hiconOrg);
  600 extern HANDLE CreatePreallocatedFile(const char* lpFileName, DWORD dwDesiredAccess,
  601     DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
  602     DWORD dwFlagsAndAttributes, LONGLONG fileSize);
  603 #define GetTextWidth(hDlg, id) GetTextSize(GetDlgItem(hDlg, id), NULL).cx
  604 
  605 DWORD WINAPI FormatThread(void* param);
  606 DWORD WINAPI SaveImageThread(void* param);
  607 DWORD WINAPI SumThread(void* param);
  608 
  609 /* Hash tables */
  610 typedef struct htab_entry {
  611     uint32_t used;
  612     char* str;
  613     void* data;
  614 } htab_entry;
  615 typedef struct htab_table {
  616     htab_entry *table;
  617     uint32_t size;
  618     uint32_t filled;
  619 } htab_table;
  620 #define HTAB_EMPTY {NULL, 0, 0}
  621 extern BOOL htab_create(uint32_t nel, htab_table* htab);
  622 extern void htab_destroy(htab_table* htab);
  623 extern uint32_t htab_hash(char* str, htab_table* htab);
  624 
  625 /* Basic String Array */
  626 typedef struct {
  627     char**   String;
  628     uint32_t Index;     // Current array size
  629     uint32_t Max;       // Maximum array size
  630 } StrArray;
  631 extern void StrArrayCreate(StrArray* arr, uint32_t initial_size);
  632 extern int32_t StrArrayAdd(StrArray* arr, const char* str, BOOL );
  633 extern int32_t StrArrayFind(StrArray* arr, const char* str);
  634 extern void StrArrayClear(StrArray* arr);
  635 extern void StrArrayDestroy(StrArray* arr);
  636 #define IsStrArrayEmpty(arr) (arr.Index == 0)
  637 
  638 /*
  639  * typedefs for the function prototypes. Use the something like:
  640  *   PF_DECL(FormatEx);
  641  * which translates to:
  642  *   FormatEx_t pfFormatEx = NULL;
  643  * in your code, to declare the entrypoint and then use:
  644  *   PF_INIT(FormatEx, Fmifs);
  645  * which translates to:
  646  *   pfFormatEx = (FormatEx_t) GetProcAddress(GetDLLHandle("fmifs"), "FormatEx");
  647  * to make it accessible.
  648  */
  649 #define         MAX_LIBRARY_HANDLES 32
  650 extern HMODULE  OpenedLibrariesHandle[MAX_LIBRARY_HANDLES];
  651 extern uint16_t OpenedLibrariesHandleSize;
  652 #define         OPENED_LIBRARIES_VARS HMODULE OpenedLibrariesHandle[MAX_LIBRARY_HANDLES]; uint16_t OpenedLibrariesHandleSize = 0
  653 #define         CLOSE_OPENED_LIBRARIES while(OpenedLibrariesHandleSize > 0) FreeLibrary(OpenedLibrariesHandle[--OpenedLibrariesHandleSize])
  654 static __inline HMODULE GetLibraryHandle(char* szLibraryName) {
  655     HMODULE h = NULL;
  656     if ((h = GetModuleHandleA(szLibraryName)) == NULL) {
  657         if (OpenedLibrariesHandleSize >= MAX_LIBRARY_HANDLES) {
  658             uprintf("Error: MAX_LIBRARY_HANDLES is too small\n");
  659         } else {
  660             h = LoadLibraryA(szLibraryName);
  661             if (h != NULL)
  662                 OpenedLibrariesHandle[OpenedLibrariesHandleSize++] = h;
  663         }
  664     }
  665     return h;
  666 }
  667 #define PF_TYPE(api, ret, proc, args)       typedef ret (api *proc##_t)args
  668 #define PF_DECL(proc)                       static proc##_t pf##proc = NULL
  669 #define PF_TYPE_DECL(api, ret, proc, args)  PF_TYPE(api, ret, proc, args); PF_DECL(proc)
  670 #define PF_INIT(proc, name)                 if (pf##proc == NULL) pf##proc = \
  671     (proc##_t) GetProcAddress(GetLibraryHandle(#name), #proc)
  672 #define PF_INIT_OR_OUT(proc, name)          do {PF_INIT(proc, name);         \
  673     if (pf##proc == NULL) {uprintf("Unable to locate %s() in %s.dll: %s\n",  \
  674     #proc, #name, WindowsErrorString()); goto out;} } while(0)
  675 #define PF_INIT_OR_SET_STATUS(proc, name)   do {PF_INIT(proc, name);         \
  676     if ((pf##proc == NULL) && (NT_SUCCESS(status))) status = STATUS_NOT_IMPLEMENTED; } while(0)
  677 
  678 /* Custom application errors */
  679 #define FAC(f)                         ((f)<<16)
  680 #define APPERR(err)                    (APPLICATION_ERROR_MASK|(err))
  681 #define ERROR_INCOMPATIBLE_FS          0x1201
  682 #define ERROR_CANT_QUICK_FORMAT        0x1202
  683 #define ERROR_INVALID_CLUSTER_SIZE     0x1203
  684 #define ERROR_INVALID_VOLUME_SIZE      0x1204
  685 #define ERROR_CANT_START_THREAD        0x1205
  686 #define ERROR_BADBLOCKS_FAILURE        0x1206
  687 #define ERROR_ISO_SCAN                 0x1207
  688 #define ERROR_ISO_EXTRACT              0x1208
  689 #define ERROR_CANT_REMOUNT_VOLUME      0x1209
  690 #define ERROR_CANT_PATCH               0x120A
  691 #define ERROR_CANT_ASSIGN_LETTER       0x120B
  692 #define ERROR_CANT_MOUNT_VOLUME        0x120C
  693 #define ERROR_BAD_SIGNATURE            0x120D
  694 #define ERROR_CANT_DOWNLOAD            0x120E