[loc] add localization support

* This is a merge up to commit bd319269aa of the localization branch
* Also fixes Clang warnings
This commit is contained in:
Pete Batard 2013-10-15 22:58:27 +01:00
parent cf3964c8a3
commit df06727416
26 changed files with 3024 additions and 491 deletions

690
res/localization/rufus.loc Normal file
View File

@ -0,0 +1,690 @@
# This file should be saved as UTF-8, no-BOM
################################################################################
l "en_US" "English (US)" 0x0409, 0x0809, 0x0c09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x3809, 0x3c09, 0x4009, 0x4409, 0x4809
g IDD_MESSAGES
t MSG_001 "Other instance detected"
t MSG_002 "Another Rufus application is running.\n"
"Please close the first application before running another one."
t MSG_003 "WARNING: ALL DATA ON DEVICE '%s' WILL BE DESTROYED.\n"
"To continue with this operation, click OK. To quit click CANCEL."
t MSG_004 "Rufus update policy"
t MSG_005 "Do you want to allow Rufus to check for application updates online?"
t MSG_006 "Close" # Must be the same as IDD_DIALOG:IDCANCEL (i.e. "Close" - I know it's confusing)
t MSG_007 "Cancel"
t MSG_008 "Yes"
t MSG_009 "No"
t MSG_010 "Bad blocks found"
t MSG_011 "Check completed: %u bad block(s) found\n"
" %d read error(s)\n %d write error(s)\n %d corruption error(s)\n"
# The following will contain the formatted message above as well as the name of the bad blocks logfile
t MSG_012 "%s\nA more detailed report can be found in:\n%s"
t MSG_013 "Disabled"
t MSG_014 "Daily"
t MSG_015 "Weekly"
t MSG_016 "Monthly"
t MSG_017 "Custom"
t MSG_018 "Your version: %d.%d.%d (Build %d)"
t MSG_019 "Latest version: %d.%d.%d (Build %d)"
# *Short* size names. These can be used as suffixes
t MSG_020 "bytes"
t MSG_021 "KB"
t MSG_022 "MB"
t MSG_023 "GB"
t MSG_024 "TB"
t MSG_025 "PB"
# *Long* size names, as they are displayed for the cluster size in the MS format dialog.
t MSG_026 "bytes" # Yes, this is a repeat from MSG_020
t MSG_027 "kilobytes"
t MSG_028 "megabytes"
t MSG_029 "Default"
# The following gets appended to the file system, cluster size, etc.
t MSG_030 "%s (Default)"
t MSG_031 "%s partition scheme for BIOS computer"
t MSG_032 "%s partition scheme for UEFI computer"
t MSG_033 "%s partition scheme for BIOS or UEFI computers"
# Number of bad block check passes (singular for 1 pass, plural for 2 or more passes)
t MSG_034 "%d Pass"
t MSG_035 "%d Passes"
t MSG_036 "ISO Image"
t MSG_037 "Application"
t MSG_038 "Abort"
t MSG_039 "Launch"
t MSG_040 "Download"
t MSG_041 "Operation cancelled by the user"
t MSG_042 "Error"
t MSG_043 "Error: %s"
t MSG_044 "File download"
t MSG_045 "USB Storage Device (Generic)"
t MSG_046 "%s (Disk %d)"
t MSG_047 "%s (%c:)"
t MSG_048 "Rufus - Flushing buffers"
t MSG_049 "Rufus - Cancellation"
# Error messages
t MSG_050 "Success."
t MSG_051 "Undetermined error while formatting."
t MSG_052 "Cannot use the selected file system for this media."
t MSG_053 "Access to the device is denied."
t MSG_054 "Media is write protected."
t MSG_055 "The device is in use by another process. "
"Please close any other process that may be accessing the device."
t MSG_056 "Quick format is not available for this device."
t MSG_057 "The volume label is invalid."
t MSG_058 "The device handle is invalid."
t MSG_059 "The selected cluster size is not valid for this device."
t MSG_060 "The volume size is invalid."
t MSG_061 "Please insert a media in drive."
t MSG_062 "An unsupported command was received."
t MSG_063 "Memory allocation error."
t MSG_064 "Read error."
t MSG_065 "Write error."
t MSG_066 "Installation failure"
t MSG_067 "Could not open media. It may be in use by another process. "
"Please re-plug the media and try again."
t MSG_068 "Error while partitioning drive."
t MSG_069 "Could not copy files to target drive."
t MSG_070 "Cancelled by user."
t MSG_071 "Unable to create formatting thread."
t MSG_072 "Bad blocks check didn't complete."
t MSG_073 "ISO image scan failure."
t MSG_074 "ISO image extraction failure."
t MSG_075 "Unable to remount volume."
t MSG_076 "Unable to patch/setup files for boot."
t MSG_077 "Unable to assign a drive letter."
t MSG_078 "Can't mount GUID volume."
t MSG_080 "Rufus detected that Windows is still flushing its internal buffers onto the USB device.\n\n"
"Depending on the speed of your USB device, this operation may take a long time to complete, "
"especially for large files.\n\nWe recommend that you let Windows finish, to avoid corruption. "
"But if you grow tired of waiting, you can just unplug the device..."
t MSG_081 "Unsupported ISO"
t MSG_082 "This version of Rufus only supports bootable ISOs based on bootmgr/WinPE, isolinux or EFI.\n"
"This ISO doesn't appear to use either..."
t MSG_083 "Replace %s?"
t MSG_084 "This ISO image seems to use an obsolete version of '%s'.\n"
"Boot menus may not display properly because of this.\n\n"
"A newer version can be downloaded by Rufus to fix this issue:\n"
"- Choose 'Yes' to connect to the internet and download the file\n"
"- Choose 'No' to leave the existing ISO file unmodified\n"
"If you don't know what to do, you should select 'Yes'.\n\n"
"Note: The new file will be downloaded in the current directory and once a "
"'%s' exists there, it will be reused automatically."
t MSG_085 "Downloading %s"
t MSG_086 "No ISO image selected"
# The content between the quotes below (\"Create a bootable disk\") should match
# the beginning of the IDC_BOOT text
t MSG_087 "Please click on the disc button to select a bootable ISO, "
"or uncheck the \"Create a bootable disk...\" checkbox."
t MSG_088 "ISO too big"
t MSG_089 "This ISO image is too big for the selected target."
t MSG_090 "Unsupported ISO"
t MSG_091 "When using UEFI Target Type, only EFI bootable ISO images are supported. "
"Please select an EFI bootable ISO or set the Target Type to BIOS."
t MSG_092 "Unsupported filesystem"
t MSG_093 "When using UEFI Target Type, only FAT/FAT32 is supported. "
"Please select FAT/FAT32 as the File system or set the Target Type to BIOS."
t MSG_094 "Non UEFI compatible ISO"
t MSG_095 "This ISO image contains a file larger than 4 GB and cannot be used to create an EFI bootable USB.\n"
"This is a limitation of UEFI/FAT32, not Rufus."
t MSG_096 "Only FAT/FAT32 is supported for this type of ISO. Please select FAT/FAT32 as the File system."
t MSG_097 "Only 'bootmgr' or 'WinPE' based ISO images can currently be used with NTFS."
t MSG_098 "FAT/FAT32 can only be used for isolinux based ISO images or when the Target Type is UEFI."
t MSG_099 "Filesystem limitation"
t MSG_100 "This iso image contains a file larger than 4GB file, which is more than the "
"maximum size allowed for a FAT or FAT32 file system."
t MSG_101 "Missing WIM support"
t MSG_102 "Your platform cannot extract files from WIM archives. WIM extraction "
"is required to create EFI bootable Windows 7 and Windows Vista USB drives. You can fix that "
"by installing a recent version of 7-Zip.\nDo you want to visit the 7-zip download page?"
t MSG_103 "Download %s?"
t MSG_104 "Syslinux v5.0 or later requires a '%s' file to be installed.\n"
"Because this file is more than 100 KB in size, and always present on Syslinux v5+ ISO images, "
"it is not embedded in Rufus.\n\nRufus can download the missing file for you:\n"
"- Select 'Yes' to connect to the internet and download the file\n"
"- Select 'No' if you want to manually copy this file on the drive later\n\n"
"Note: The file will be downloaded in the current directory and once a "
"'%s' exists there, it will be reused automatically.\n"
t MSG_105 "Cancelling may leave the device in an UNUSABLE state.\n"
"If you are sure you want to cancel, click YES. Otherwise, click NO."
t MSG_106 "Please select folder"
t MSG_107 "All files"
t MSG_108 "Rufus log"
t MSG_109 "0x%02X (Disk %d)"
# Tootips
# Partition Scheme and Target Type
t MSG_150 "Usually the safest choice. If you have an UEFI computer and want to install "
"an OS in EFI mode however, you should select one of the options below"
t MSG_151 "Use this if you want to install an OS in EFI mode, but need to access "
"the USB content from Windows XP"
t MSG_152 "The preferred option to install an OS in EFI mode and when "
"USB access is not required for Windows XP"
t MSG_153 "Test pattern: 0x%02X"
t MSG_154 "Test pattern: 0x%02X, 0x%02X"
t MSG_155 "Test pattern: 0x%02X, 0x%02X, 0x%02X"
t MSG_156 "Test pattern: 0x%02X, 0x%02X, 0x%02X, 0x%02X"
t MSG_157 "Sets the target filesystem"
t MSG_158 "Minimum size that a block of data will occupy in the filesystem"
t MSG_159 "Use this field to set the drive label\nInternational characters are accepted"
t MSG_160 "Toggle advanced options"
t MSG_161 "Check the device for bad blocks using a test pattern"
t MSG_162 "Uncheck this box to use the \"slow\" format method"
t MSG_163 "Check this box to make the USB drive bootable"
t MSG_164 "Method that will be used to make the drive bootable"
t MSG_165 "Click to select an ISO..."
t MSG_166 "Check this box to allow the display of international labels "
"and set a device icon (creates an autorun.inf)"
t MSG_167 "Install an MBR that allows boot selection and can masquerade the BIOS USB drive ID"
t MSG_168 "Try to masquerade first bootable USB drive (usually 0x80) as a different disk.\n"
"This should only be necessary if you install Windows XP and have more than one disk"
t MSG_169 "Create an extra hidden partition and try to align partitions boundaries.\n"
"This can improve boot detection for older BIOSes"
t MSG_170 "Enable detection for disks not normally detected by Rufus. USE AT YOUR OWN RISKS!!!"
t MSG_171 "Start the formatting operation.\nThis will DESTROY any data on the target!"
t MSG_172 "Licensing information and credits"
t MSG_173 "Click to select..."
# The following will appear in the about dialog
t MSG_174 "Rufus - The Reliable USB Formatting Utility"
t MSG_175 "Version %d.%d.%d (Build %d)"
t MSG_176 ""
t MSG_177 "Report bugs or request enhancements at:"
t MSG_178 "Additional Copyrights:"
t MSG_179 "Update Policy:"
t MSG_180 "If you choose to allow this program to check for application updates, "
"you agree that the following information may be collected on our server(s):"
t MSG_181 "Your operating system's architecture and version"
t MSG_182 "The version of the application you use"
t MSG_183 "Your IP address"
t MSG_184 "For the purpose of generating private usage statistics, we may keep the information collected, "
"\\b for at most a year\\b0 . However, we will not willingly disclose any of this individual data to third parties."
t MSG_185 "Update Process:"
t MSG_186 "Rufus does not install or run background services, therefore update checks are performed only when the main application is running.\\line\n"
"Internet access is of course required when checking for updates."
# Status messages - these messages will appear on the status bar
t MSG_201 "Cancelling - Please wait..."
t MSG_202 "Scanning ISO image..."
t MSG_203 "Failed to scan ISO image"
# Parameter: the name of an obsolete Syslinux .c32 module. eg: "Obsolete vesamenu.c32 detected"
t MSG_204 "Obsolete %s detected"
# Display the name of the ISO selected. eg: "Using ISO: en_win7_x64_sp1.iso"
t MSG_205 "Using ISO: %s"
# Typically "Missing ldlinux.c32 file"
t MSG_206 "Missing %s file"
# Same message, once for singular and plural ("1 device found", "2 devices found")
t MSG_208 "%d device found"
t MSG_209 "%d devices found"
t MSG_210 "DONE."
t MSG_211 "Cancelled."
t MSG_212 "FAILED."
# Used when a new update has been downloaded and lauched
t MSG_213 "Launching new application..."
t MSG_214 "Failed to launch new application"
# Open/Save file
t MSG_215 "Opened %s"
t MSG_216 "Saved %s"
# Formatting status (make sure you use a double % to print the percent sign)
t MSG_217 "Formatting: %0.1f%% completed"
t MSG_218 "Creating file system: Task %d/%d completed"
t MSG_219 "NTFS Fixup: %d%% completed"
t MSG_221 "Setting Label (This may take while)..."
# Parameter: the file system. eg. "Formatting (NTFS)..."
t MSG_222 "Formatting (%s)..."
t MSG_223 "NTFS Fixup (Checkdisk)..."
t MSG_224 "Clearing MBR/PBR/GPT structures..."
t MSG_225 "Requesting disk access..."
t MSG_226 "Analyzing existing boot records..."
t MSG_227 "Closing existing volume..."
t MSG_228 "Writing master boot record..."
t MSG_229 "Writing partition boot record..."
t MSG_230 "Copying DOS files..."
t MSG_231 "Copying ISO files..."
t MSG_232 "Win7 EFI boot setup (this may take a while)..."
t MSG_233 "Finalizing, please wait..."
# Takes the Syslinux version as paramete. eg. "Installing Syslinux v5..."
t MSG_234 "Installing Syslinux v%d..."
# Bad blocks status. eg: "Bad Blocks: PASS 1/2 - 12.34% (0/0/1 errors)"
t MSG_235 "Bad Blocks: PASS %d/%d - %0.2f%% (%d/%d/%d errors)"
t MSG_236 "Bad Blocks: Testing with random pattern"
t MSG_237 "Bad Blocks: Testing with pattern 0x%02X"
# eg. "Partitioning (MBR)..."
t MSG_238 "Partitioning (%s)..."
t MSG_239 "Deleting partitions..."
t MSG_240 "Downloading %s: Connecting..."
t MSG_241 "Downloading: %0.1f%%"
t MSG_242 "Failed to download file."
t MSG_243 "Checking for Rufus updates..."
t MSG_244 "Updates: Unable to connect to the internet"
t MSG_245 "Updates: Unable to acces version data"
t MSG_246 "A new version of Rufus is available!"
t MSG_247 "No new version of Rufus was found"
t MSG_248 "Application registry keys successfully deleted"
t MSG_249 "Failed to delete application registry keys"
# eg. "Fixed disk detection enabled" "ISO size check disabled"
t MSG_250 "%s enabled"
t MSG_251 "%s disabled"
t MSG_252 "Size checks"
t MSG_253 "Fixed disks detection"
t MSG_254 "Force large FAT32 formatting"
t MSG_255 "NoDriveTypeAutorun will be deleted on exit"
t MSG_256 "Fake drive detection"
t MSG_257 "Joliet support"
t MSG_258 "Rock Ridge support"
################################################################################
l "fr_FR" "French" 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c
g IDD_DIALOG
t IDS_DEVICE_TXT "Periphérique"
t IDS_PARTITION_TYPE_TXT "Type de partition et système de destination"
t IDS_FILESYSTEM_TXT "Système de fichiers"
t IDS_CLUSTERSIZE_TXT "Taille de clusters"
t IDS_LABEL_TXT "Nouveau label"
t IDS_FORMAT_OPTIONS_GRP "Options de Formattage "
t IDC_BADBLOCKS "Vérification de mauvais blocs:"
s IDC_BADBLOCKS +10,0
m IDC_NBPASSES +5,0
t IDC_QUICKFORMAT "Formattage rapide"
t IDC_BOOT "Disque de démarrage utilisant:"
s IDC_BOOT +5,0
m IDC_BOOTTYPE +5,0
m IDC_SELECT_ISO +3,0
t IDC_SET_ICON "Ajouter un label étendu et une icône"
m IDC_ADVANCED +36,0
t IDC_ABOUT "A propos..."
t IDCANCEL "Fermer"
t IDC_START "Démarrer"
t IDS_ADVANCED_OPTIONS_GRP "Options avancées"
t IDC_ENABLE_FIXED_DISKS "Lister les disques fixes ou non partitionés"
t IDC_EXTRA_PARTITION "Options de compatibilité avec anciens BIOS"
t IDC_RUFUS_MBR "Ajout du MBR Rufus, ID BIOS:"
m IDC_DISK_ID +5,0
s IDC_DISK_ID -2,0
g IDD_ABOUTBOX
t IDD_ABOUTBOX "A propos de Rufus"
t IDC_ABOUT_LICENSE "License"
t IDC_ABOUT_UPDATES "Mises à jour"
g IDD_LICENSE
t IDD_LICENSE "License Rufus"
g IDD_NOTIFICATION
t IDC_MORE_INFO "Plus d'info..."
t IDYES "Oui"
t IDNO "Non"
g IDD_LOG
t IDC_LOG_CLEAR "Effacer"
t IDC_LOG_SAVE "Enregistrer"
t IDCANCEL "Fermer"
g IDD_UPDATE_POLICY
s IDD_UPDATE_POLICY +30,0
t IDD_UPDATE_POLICY "Paramètres de mises à jour"
s IDC_POLICY +30,0
t IDS_UPDATE_SETTINGS_GRP "Options"
s IDS_UPDATE_SETTINGS_GRP +20,0
t IDS_UPDATE_FREQUENCY_TXT "Recherche mises à jour:"
s IDS_UPDATE_FREQUENCY_TXT -3,0
t IDS_INCLUDE_BETAS_TXT "Inclure les bétas:"
m IDC_UPDATE_FREQUENCY -3,0
m IDC_INCLUDE_BETAS -3,0
s IDC_UPDATE_FREQUENCY +25,0
m IDS_CHECK_NOW_GRP 20,0
s IDS_CHECK_NOW_GRP +10,0
t IDC_CHECK_NOW "Chercher maintenant"
m IDC_CHECK_NOW 9,0
s IDC_CHECK_NOW +31,0
t IDCANCEL "Fermer"
m IDCANCEL 9,0
g IDD_NEW_VERSION
t IDD_NEW_VERSION "Mise à jour de Rufus"
t IDS_NEW_VERSION_AVAIL_TXT "Une nouvelle version est disponible. Veuillez télécharger la nouvelle version !"
t IDC_WEBSITE "Cliquez ici pour aller sur le site de Rufus"
t IDS_NEW_VERSION_NOTES_GRP "Notes relatives à cette version"
t IDS_NEW_VERSION_DOWNLOAD_GRP "Téléchargement"
t IDC_DOWNLOAD ""Télécharger""
t IDCANCEL "Fermer"
g IDD_ISO_EXTRACT
t IDD_ISO_EXTRACT "Copie des fichier ISO..."
t IDC_ISO_FILENAME "Ouverture de l'image - veuillez patienter..."
t IDC_ISO_ABORT "Annuler"
g IDD_MESSAGES
t MSG_001 "Autre instance detectée"
t MSG_002 "Une autre instance de Rufus est en cours d'exécution.\n"
"Veuillez fermer la première instance avant d'en lancer une seconde."
t MSG_003 "ATTENTION: TOUTES LES DONNEES DU VOLUME '%s' VONT ETRE EFFACEES.\n"
"Pour continuer cette operation, cliquez sur OK.\nPour quitter cliquez sur ANNULER."
t MSG_004 "Mises à jour"
t MSG_005 "Voulez-vous authoriser Rufus à chercher des mises à jour en ligne?"
t MSG_006 "Fermer"
t MSG_007 "Annuler"
t MSG_008 "Oui"
t MSG_009 "Non"
t MSG_010 "Blocs défectueux détectés"
t MSG_011 "Vérification complète: %u bloc(s) défectueux détecté(s)\n"
" %d erreur(s) de lecture\n %d erreur(s) d'écriture\n %d erreur(s) de corruption\n"
t MSG_012 "%s\nUn rapport plus détaillé peut être obtenu à:\n%s"
t MSG_013 "Jamais"
t MSG_014 "Quotidienne"
t MSG_015 "Hebdomadaire"
t MSG_016 "Mensuelle"
t MSG_017 "Personalisée"
t MSG_018 "Votre version: %d.%d.%d (Build %d)"
t MSG_019 "Dernière version: %d.%d.%d (Build %d)"
t MSG_020 "octets"
t MSG_021 "Ko"
t MSG_022 "Mo"
t MSG_023 "Go"
t MSG_024 "To"
t MSG_025 "Po"
t MSG_026 "octets"
t MSG_027 "kilo-octets"
t MSG_028 "mega-octets"
t MSG_029 "Défaut"
t MSG_030 "%s (Défaut)"
t MSG_031 "Type de partition %s pour ordinateur BIOS"
t MSG_032 "Type de partition %s pour ordinateur UEFI"
t MSG_033 "Type de partition %s pour ordinateur BIOS ou UEFI"
t MSG_034 "%d passe"
t MSG_035 "%d passes"
t MSG_036 "Image ISO"
t MSG_037 "Application"
t MSG_038 "Annuler"
t MSG_039 "Lancer"
t MSG_040 "Télécharger"
t MSG_041 "Operation annulée par l'utilisateur"
t MSG_042 "Erreur"
t MSG_043 "Erreur: %s"
t MSG_044 "Téléchargement de fichier"
t MSG_045 "Pérpih. de stockage USB (Générique)"
t MSG_046 "%s (Disque %d)"
t MSG_047 "%s (%c:)"
t MSG_048 "Rufus - Flush de la mémoire tampon"
t MSG_049 "Rufus - Annulation"
# Error messages
t MSG_050 "Opération réussie."
t MSG_051 "Erreur indéterminéee lors du formatage."
t MSG_052 "Ce système de fichiers ne peut pas être utilisé ici."
t MSG_053 "L'accès au périphérique est refusé."
t MSG_054 "Le périphérique est protegé en écriture."
t MSG_055 "Le périphérique est en cours d'utilisation par une autre application. "
"Veuillez fermer toute autre application succeptible d'accéder au périphérique."
t MSG_056 "Le formatage rapide n'est pas disponible pour ce périphérique."
t MSG_057 "Le nom de volume est invalide."
t MSG_058 "Le handle de périphérique est invalide."
t MSG_059 "Cette taille de cluster n'est pas appliquable ici."
t MSG_060 "La taille du volume est invalide."
t MSG_061 "Veuillez insérer un média dans le lecteur."
t MSG_062 "Commande non supportée."
t MSG_063 "Erreur d'allocation mémoire."
t MSG_064 "Erreur de lecture."
t MSG_065 "Erreur d'écriture."
t MSG_066 "L'installation a échoué"
t MSG_067 "Impossible d'accéder au média. Il peut être en cours d'utilisation par une autre application. "
"Essayer de déconnecter le média et essayez à nouveau."
t MSG_068 "Erreur de partitionement."
t MSG_069 "Impossible de copier les fichiers sur le périphérique de detination."
t MSG_070 "Opération annulée par l'utilisateur."
t MSG_071 "Impossible de créer le thread de formattage."
t MSG_072 "La vérification de blocs défectueux a été interrompue."
t MSG_073 "Echec d'analyse de l'image ISO."
t MSG_074 "Echec d'extraction de l'image ISO."
t MSG_075 "Echec lors du remontage du volume."
t MSG_076 "Echec de modification des fichiers de démarrage."
t MSG_077 "Echec d'assignation d'une lettre de volume."
t MSG_078 "Impossible de monter le volume GUID."
t MSG_080 "Rufus a detecté que Windows est en train de finir de vider la mémoire tampon.\n\n"
"En fonction de la vitesse de votre périphérique, cette opération peut prendre beaucoup de temps, "
"surtout s'il s'agit d'un fichier volumineux.\n\nNous recommandons d'attendre que Windows "
"complète cette opération, afin d'éviter la corruption du périphérique. Mais si jamais cela prend "
"trop de temps, vous pouvez toujours essayer de déconnecter le média..."
t MSG_081 "Image ISO non supportée"
t MSG_082 "Cette version de Rufus supporte seulement les ISOs démarrables qui utilisent bootmgr/WinPE, isolinux ou EFI.\n"
"Cette image ISO ne semble pas utiliser une de ces options..."
t MSG_083 "Remplacer %s?"
t MSG_084 "Cette image ISO utilise une version obsolète du fichier '%s'.\n"
"A cause de cela, les menus de démarrage peuvent de pas fonctionner.\n\n"
"Une nouvelle version du fichier peut être téléchargée par Rufus pour addresser ce problème:\n"
"- Choisissez 'Oui' pour télécharger le fichier depuis Internet\n"
"- Choisissez 'Non' pour garder le fichier de l'image ISO\n"
"Si vous ne savez pas quoi faire, sélectionnez 'Oui'.\n\n"
"Note: Le nouveau fichier est téléchargé dans le répertoire courrant. Une fois qu'un fichier"
"'%s' existe à cet endroit, il sera réutilisé automatiquement."
t MSG_085 "Téléchargement de %s"
t MSG_086 "Aucune image ISO sélectionnée"
t MSG_087 "Veuillez cliquer sur le bouton avec un disque pour choisir une image ISO démarrable "
"ou décochez l'option \"Disque de démarrage...\"."
t MSG_088 "Image ISO trop large"
t MSG_089 "Cette ISO image est trop large pour le périphérique sélectionné."
t MSG_090 "Image ISO on supportée"
t MSG_091 "Quand UEFI est séelectionné, seules les images ISO basées sur EFI sont supportées. "
"Veuillez sélectionner une image ISO démarrable avec EFI ou sélectionner BIOS pour le système de destination."
t MSG_092 "Système de fichiers non supporté"
t MSG_093 "Quand UEFI est séelectionné, seul le système de fichiers FAT/FAT32 est supporté. "
"Veuillez sélectionner FAT/FAT32 comme système de fichiers ou sélectionner BIOS pour le système de destination."
t MSG_094 "Image ISO incompatible avec UEFI"
t MSG_095 "Cette image ISO contient un fichier de plus de 4 Go et ne peut pas être utilisée pour créer un USB démarrable par UEFI.\n"
"Ceci est une limitation de UEFI/FAT32, pas de Rufus."
t MSG_096 "Seul FAT/FAT32 est supporté avec ce type d'image ISO. Veuillez sélectionner FAT/FAT32 pour le système de fichiers."
t MSG_097 "Seules les images ISO utilisant 'bootmgr' ou 'WinPE' peuvent être utilisées avec NTFS."
t MSG_098 "FAT/FAT32 peut seulement être utilisé pour les images ISO utilisant 'isolinux' ou lorsque que le système de destination est UEFI."
t MSG_099 "Limitation du système de fichiers"
t MSG_100 "Cette image ISO contient un fichier de plus de 4 Go, ce qui est plus que la taille maximum "
"supportée par le système de fichiers FAT ou FAT32."
t MSG_101 "Support pour archives WIM non disponible"
t MSG_102 "Votre plateforme ne peut pas extraire les fichiers depuis les archives WIM. L'extraction de données WIM "
"est nécéssaire pour créer des médias USB démarrable avec EFI pour Windows 7/8 ou Windows Vista. Vous pouvez addresser "
"ce problème en téléchargeant une version récente de l'utilitaire 7-Zip.\nVoulez-vous visiter la page de téléchargements de 7-zip?"
t MSG_103 "Télécharger %s?"
t MSG_104 "Syslinux v5.0 ou plus récent requiert l'installtion d'un fichier '%s'.\n"
"Puisque ce fichier fait plus de 100 Ko et est toujours présent sur les images ISO à base de Syslinux v5+, "
"il n'est pas inclus dans l'application.\n\nRufus peut télécharger ce fichier pour vous:\n"
"- Choisissez 'Oui' pour télécharger le fichier depuis Internet\n"
"- Choisissez 'Non' si vous compter copier ce fichier manuellement\n"
"Note: Ce fichier est téléchargé dans le répertoire courrant. Une fois qu'un fichier"
"'%s' existe à cet endroit, il sera réutilisé automatiquement."
t MSG_105 "Annuler peut laisser le périphérique dans un état inutilisable.\n"
"Si vous êtes sûr de vouloir annuler, sélectionnez OUI. Sinon, sélectionnez NON."
t MSG_106 "Sélection de répertoire"
t MSG_107 "Tous les fichiers"
t MSG_108 "Log Rufus"
t MSG_109 "0x%02X (disque %d)"
# Tootips
t MSG_150 "Choix le plus sûr. Si toutefois vous possédez un ordinateur à base de UEFI et voulez installer "
"un Système dexploitation en mode EFI, vous devriez plutôt sélectionner lune des options ci-dessous"
t MSG_151 "Utilisez cette options si vous comptez installer un Système dexploitation en mode EFI "
"et avez aussi besoin daccéder au contenu du média sous Windows XP"
t MSG_152 "Option préférée pour installer un Système dexploitation en mode EFI, "
"quand laccès au média depuis Windows XP nest pas nécessaire"
t MSG_153 "Motif de test: 0x%02X"
t MSG_154 "Motif de test: 0x%02X, 0x%02X"
t MSG_155 "Motif de test: 0x%02X, 0x%02X, 0x%02X"
t MSG_156 "Motif de test: 0x%02X, 0x%02X, 0x%02X, 0x%02X"
t MSG_157 "Sélectionne le système de fichiers"
t MSG_158 "La taille minimum quun bloc de données occupera sur le système de fichiers"
t MSG_159 "Utilisez ce champ pour mettre à jour le nom du volume\n"
"Les caractères étendus et les accents sont acceptés "
t MSG_160 "Affiche/Cache les options avancées "
t MSG_161 "Détecte la présence de blocs défectueux en utilisant un motif de test"
t MSG_162 "Décochez cette case pour utiliser la méthode de formatage \"lente\" "
t MSG_163 "Cochez cette case pour rendre le périphérique démarrable"
t MSG_164 "Méthode à utiliser pour rendre le périphérique démarrable "
t MSG_165 "Cliquez ici pour sélectionner une image ISO..."
t MSG_166 "Cochez cette case pour permettre laffichage des caractères étendus/internationaux "
"et ajouter une icône (créé un fichier autorun.inf)"
t MSG_167 "Installe un MBR permettant la sélection du périphérique de démarrage. Peut aussi "
"camoufler lID de disque pour le BIOS "
t MSG_168 "Camoufle le premier disque USB démarrable (généralement 0x80) sous une ID différente.\n"
"Changez cette option si vous installez Windows XP avec plus dun disque dur"
t MSG_169 "Créé une petite partition supplémentaire et essaye daligner les partitions.\n"
"Peut améliorer la détection USB pour les vieux BIOS"
t MSG_170 "Active la détection de disque non normalement listés par Rufus. UTILISEZ A VOS PROPRES RISQUES !!! "
t MSG_171 "Lance le formatage. DETRUIT toutes les données existantes sur la cible !"
t MSG_172 "Licence dutilisation et remerciements"
t MSG_173 "Cliquez pour sélectionner..."
t MSG_174 "Rufus - The Reliable USB Formatting Utility"
t MSG_175 "Version %d.%d.%d (Build %d)"
t MSG_176 "Traduction Française: Pete Batard"
t MSG_177 "Soumettre un bug ou une demande d'amélioration à:"
t MSG_178 "Copyrights supplémentaires:"
t MSG_179 "Politique de mises à jour:"
t MSG_180 "Si vous autorisez ce programme à chercher les mises à jour, vous acceptez "
"que les informations suivantes peuvent être collectées sur nos serveurs:"
t MSG_181 "Larchitecture de votre système dexploitation ainsi que sa version"
t MSG_182 "La version de lapplication que vous utilisez"
t MSG_183 "Votre adresse IP"
t MSG_184 "Afin de générer des statistiques dutilisation privées, il se peut que nous gardions "
"les informations ainsi obtenues \\b au plus un an\\b0 . A moins dy être contraint par la loi, "
"nous nous engageons aussi à ne pas diffuser ces informations à de tierce parties."
t MSG_185 "Processus de mise à jour:"
t MSG_186 "Aucun service ou tâche de fond ne sont installés ou lancés par Rufus. Cela veut dire que les "
"test de mises à jour interviennent seulement lorsque lapplication principale s'exécute.\\line\n"
"Bien entendu, un accès à internet est requis pour vérifier la disponibilité des mises à jour."
# Status messages
t MSG_201 "Annulation - Veuillez patienter..."
t MSG_202 "Analyse de l'image ISO..."
t MSG_203 "Echec d'analyse de l'image ISO"
t MSG_204 "Fichier %s obsolète detecté"
t MSG_205 "ISO utilisée: %s"
t MSG_206 "Fichier %s manquant"
t MSG_208 "%d périphérique détecté"
t MSG_209 "%d périphériques détectés"
t MSG_210 "Opération terminée."
t MSG_211 "Opération annulée."
t MSG_212 "ECHEC."
t MSG_213 "Lancement de la nouvelle application..."
t MSG_214 "Echec de lancement de l'application"
t MSG_215 "%s ouvert"
t MSG_216 "%s sauvegardé"
t MSG_217 "Formatage: %0.1f%% complet"
t MSG_218 "Création du système de fichiers: Tâche %d/%d complète"
t MSG_219 "Finalisation NTFS: %d%% complète"
t MSG_221 "Ecriture du label (peut prendre du temps)..."
t MSG_222 "Formatage (%s)..."
t MSG_223 "Finalisation NTFS (Checkdisk)..."
t MSG_224 "Effacement des structures MBR/PBR/GPT..."
t MSG_225 "Requête d'accès disque..."
t MSG_226 "Analyse des structures de boot existantes..."
t MSG_227 "Fermeture des volumes existants..."
t MSG_228 "Ecriture du MBR..."
t MSG_229 "Ecriture du PBR..."
t MSG_230 "Copie des fichiers DOS..."
t MSG_231 "Copie des fichiers ISO..."
t MSG_232 "Ecriture boot Win7 EFI (peut prendre du temps)..."
t MSG_233 "Finalisation, veuillez patienter..."
t MSG_234 "Installation de Syslinux v%d..."
t MSG_235 "Défauts: PASSE %d/%d - %0.2f%% (%d/%d/%d erreurs)"
t MSG_236 "Défauts: Test avec motif aléatoire"
t MSG_237 "Défauts: Test avec motif 0x%02X"
t MSG_238 "Partitionage (%s)..."
t MSG_239 "Effaçement des partitions..."
t MSG_240 "Télechargement de %s: Connection..."
t MSG_241 "Télechargement: %0.1f%%"
t MSG_242 "Echec de télechargement du fichier"
t MSG_243 "Recherche des mises à jour..."
t MSG_244 "MAJ: Impossible de se connecter"
t MSG_245 "MAJ: Pas d'accès aux données de mises à jour"
t MSG_246 "Une nouvelle version de Rufus est disponible !"
t MSG_247 "Pas de mise à jour"
t MSG_248 "Clés de registre supprimées"
t MSG_249 "Echec de suppression des clés registres"
t MSG_250 "%s activé"
t MSG_251 "%s désactivé"
t MSG_252 "Tests de dépassement de taille"
t MSG_253 "Détection de disques fixes"
t MSG_254 "Force 'large FAT32'"
t MSG_255 "NoDriveTypeAutorun sera effacé en sortie"
t MSG_256 "Test de contrefaçons"
t MSG_257 "Support Joliet"
t MSG_258 "Support Rock Ridge"
################################################################################
l "zh_CN" "Chinese (Traditional)" 0x0404, 0x0804, 0x0c04, 0x1004, 0x1404
g IDD_DIALOG
t IDS_DEVICE_TXT "设备"
t IDS_PARTITION_TYPE_TXT "分区计划和目标系统类型"
t IDS_FILESYSTEM_TXT "文件系统"
t IDS_CLUSTERSIZE_TXT "簇的大小"
t IDS_LABEL_TXT "新卷标"
t IDS_FORMAT_OPTIONS_GRP "格式选项 "
t IDC_BADBLOCKS "检查设备的坏块:"
t IDC_QUICKFORMAT "快速格式化"
t IDC_BOOT "创建一个可启动的磁盘使用:"
s IDC_BOOT +10,0
t IDC_SET_ICON "创建扩展标签和图标文件"
m IDC_ADVANCED -24,0
m IDC_NBPASSES 8,0
m IDC_BOOTTYPE 8,0
m IDC_SELECT_ISO 6,0
t IDC_ABOUT "关于..."
t IDC_LOG "日志"
m IDC_LOG -5,0
s IDC_LOG +5,0
t IDCANCEL "关闭"
t IDC_START "开始"
t IDS_ADVANCED_OPTIONS_GRP "高级选项"
t IDC_ENABLE_FIXED_DISKS "列表固定(非flash)或USB磁盘分区"
t IDC_EXTRA_PARTITION "添加修复旧的BIOS额外的分区校准等等"
t IDC_RUFUS_MBR "使用 Rufus MBR BIOS ID:"
g IDD_ABOUTBOX
t IDD_ABOUTBOX "关于 Rufus"
t IDC_ABOUT_LICENSE "许可证"
t IDC_ABOUT_UPDATES "更新"
t IDOK "确定"
g IDD_LICENSE
t IDD_LICENSE "Rufus 许可证"
t IDOK "取消"
g IDD_NOTIFICATION
t IDD_NOTIFICATION "更新方案和设置"
t IDC_MORE_INFO "更多信息"
t IDYES "是"
t IDNO "否"
g IDD_LOG
t IDD_LOG "日志"
t IDC_LOG_CLEAR "清除日志"
t IDC_LOG_SAVE "保存日志"
t IDCANCEL "关闭日志"
g IDD_LICENSE
t IDOK "取消"
g IDD_UPDATE_POLICY
t IDD_UPDATE_POLICY "更新方案和设置"
t IDS_UPDATE_SETTINGS_GRP "设置"
t IDS_UPDATE_FREQUENCY_TXT "检查更新:"
t IDS_INCLUDE_BETAS_TXT "包括测试版本:"
t IDC_CHECK_NOW "立即检查"
t IDCANCEL "取消"
g IDD_NEW_VERSION
t IDD_NEW_VERSION "检查更新 - Rufus"
t IDS_NEW_VERSION_AVAIL_TXT "更新的版本可用。请下载最新版本!"
t IDC_WEBSITE "点击这里进入网站"
t IDS_NEW_VERSION_NOTES_GRP "发行说明"
t IDS_NEW_VERSION_DOWNLOAD_GRP "下载"
t IDC_DOWNLOAD "下载"
t IDCANCEL "取消"
g IDD_ISO_EXTRACT
t IDD_ISO_EXTRACT "复制ISO文件..."
t IDC_ISO_FILENAME "打开ISO映像 - 请稍候..."
t IDC_ISO_ABORT "取消"
g IDD_MESSAGES
t MSG_004 "更新方案和设置"
t MSG_005 "你要允許此應用程序檢查更新?"
t MSG_006 "关闭"
t MSG_007 "撤消"

View File

@ -87,6 +87,7 @@
<AdditionalIncludeDirectories>..\msvc-missing;..\ms-sys\inc;..\syslinux\libinstaller;..\syslinux\libfat;..\libcdio;..\getopt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<AdditionalDependencies>setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -113,6 +114,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>CompileAsC</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<AdditionalDependencies>setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -135,6 +137,7 @@
<AdditionalIncludeDirectories>..\msvc-missing;..\ms-sys\inc;..\syslinux\libinstaller;..\syslinux\libfat;..\libcdio;..\getopt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<AdditionalDependencies>setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -160,6 +163,7 @@
<AdditionalIncludeDirectories>..\msvc-missing;..\ms-sys\inc;..\syslinux\libinstaller;..\syslinux\libfat;..\libcdio;..\getopt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<AdditionalDependencies>setupapi.lib;comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -181,6 +185,7 @@
<ClCompile Include="..\dos.c" />
<ClCompile Include="..\icon.c" />
<ClCompile Include="..\iso.c" />
<ClCompile Include="..\localization.c" />
<ClCompile Include="..\net.c" />
<ClCompile Include="..\parser.c" />
<ClCompile Include="..\rufus.c" />
@ -197,6 +202,8 @@
<ClInclude Include="..\libcdio\cdio\iso9660.h" />
<ClInclude Include="..\libcdio\cdio\logging.h" />
<ClInclude Include="..\libcdio\cdio\udf.h" />
<ClInclude Include="..\localization.h" />
<ClInclude Include="..\localization_data.h" />
<ClInclude Include="..\msapi_utf8.h" />
<ClInclude Include="..\dos.h" />
<ClInclude Include="..\registry.h" />

View File

@ -60,6 +60,9 @@
<ClCompile Include="..\stdfn.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\localization.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\rufus.h">
@ -101,6 +104,12 @@
<ClInclude Include="..\registry.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\localization.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\localization_data.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\res\rufus.ico">

View File

@ -36,6 +36,7 @@ SOURCES=rufus.c \
stdlg.c \
icon.c \
parser.c \
localization.c \
net.c \
iso.c \
dos.c \

View File

@ -9,7 +9,7 @@ pkg_v_rc_0 = @echo " RC $@";
%_rc.o: %.rc
$(pkg_v_rc)$(WINDRES) $(AM_RCFLAGS) -i $< -o $@
rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdfn.c stdlg.c rufus.c
rufus_SOURCES = drive.c icon.c parser.c localization.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdfn.c stdlg.c rufus.c
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS)
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \

View File

@ -44,12 +44,13 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_rufus_OBJECTS = rufus-drive.$(OBJEXT) rufus-icon.$(OBJEXT) \
rufus-parser.$(OBJEXT) rufus-iso.$(OBJEXT) rufus-net.$(OBJEXT) \
rufus-dos.$(OBJEXT) rufus-dos_locale.$(OBJEXT) \
rufus-badblocks.$(OBJEXT) rufus-syslinux.$(OBJEXT) \
rufus-vhd.$(OBJEXT) rufus-format.$(OBJEXT) \
rufus-stdio.$(OBJEXT) rufus-stdfn.$(OBJEXT) \
rufus-stdlg.$(OBJEXT) rufus-rufus.$(OBJEXT)
rufus-parser.$(OBJEXT) rufus-localization.$(OBJEXT) \
rufus-iso.$(OBJEXT) rufus-net.$(OBJEXT) rufus-dos.$(OBJEXT) \
rufus-dos_locale.$(OBJEXT) rufus-badblocks.$(OBJEXT) \
rufus-syslinux.$(OBJEXT) rufus-vhd.$(OBJEXT) \
rufus-format.$(OBJEXT) rufus-stdio.$(OBJEXT) \
rufus-stdfn.$(OBJEXT) rufus-stdlg.$(OBJEXT) \
rufus-rufus.$(OBJEXT)
rufus_OBJECTS = $(am_rufus_OBJECTS)
rufus_DEPENDENCIES = rufus_rc.o ms-sys/libmssys.a \
syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
@ -184,7 +185,7 @@ SUBDIRS = ms-sys syslinux/libfat syslinux/libinstaller libcdio/iso9660 libcdio/u
pkg_v_rc = $(pkg_v_rc_$(V))
pkg_v_rc_ = $(pkg_v_rc_$(AM_DEFAULT_VERBOSITY))
pkg_v_rc_0 = @echo " RC $@";
rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdfn.c stdlg.c rufus.c
rufus_SOURCES = drive.c icon.c parser.c localization.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdfn.c stdlg.c rufus.c
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS)
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
@ -269,6 +270,14 @@ rufus-parser.obj: parser.c
$(AM_V_CC) @AM_BACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-parser.obj `if test -f 'parser.c'; then $(CYGPATH_W) 'parser.c'; else $(CYGPATH_W) '$(srcdir)/parser.c'; fi`
rufus-localization.o: localization.c
$(AM_V_CC) @AM_BACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-localization.o `test -f 'localization.c' || echo '$(srcdir)/'`localization.c
rufus-localization.obj: localization.c
$(AM_V_CC) @AM_BACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-localization.obj `if test -f 'localization.c'; then $(CYGPATH_W) 'localization.c'; else $(CYGPATH_W) '$(srcdir)/localization.c'; fi`
rufus-iso.o: iso.c
$(AM_V_CC) @AM_BACKSLASH@
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-iso.o `test -f 'iso.c' || echo '$(srcdir)/'`iso.c

View File

@ -45,6 +45,8 @@
#include "badblocks.h"
#include "file.h"
#include "msapi_utf8.h"
#include "resource.h"
#include "localization.h"
FILE* log_fd = NULL;
static const char* abort_msg = "Too many bad blocks, aborting test\n";
@ -326,12 +328,12 @@ static void print_status(void)
percent = calc_percent((unsigned long) currently_testing,
(unsigned long) num_blocks);
percent = (percent/2.0f) + ((cur_op==OP_READ)? 50.0f : 0.0f);
PrintStatus(0, FALSE, "Bad Blocks: PASS %d/%d - %0.2f%% (%d/%d/%d errors)",
PrintStatus(0, FALSE, lmprintf(MSG_235,
cur_pattern, nr_pattern,
percent,
percent,
num_read_errors,
num_write_errors,
num_corruption_errors);
num_corruption_errors));
UpdateProgress(OP_BADBLOCKS, (((cur_pattern-1)*100.0f) + percent) / nr_pattern);
}
@ -357,7 +359,7 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern,
for (ptr = buffer; ptr < buffer + n; ptr++) {
(*ptr) = rand() % (1 << (8 * sizeof(char)));
}
PrintStatus(3500, FALSE, "Bad Blocks: Testing with random pattern.");
PrintStatus(3500, FALSE, lmprintf(MSG_236));
} else {
bpattern[0] = 0;
for (i = 0; i < sizeof(bpattern); i++) {
@ -374,7 +376,7 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern,
else
i--;
}
PrintStatus(3500, FALSE, "Bad Blocks: Testing with pattern 0x%02X.", bpattern[i]);
PrintStatus(3500, FALSE, lmprintf(MSG_237, bpattern[i]));
cur_pattern++;
}
}
@ -427,7 +429,7 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size,
size_t blocks_at_once, int nb_passes)
{
unsigned char *buffer = NULL, *read_buffer;
const unsigned int pattern[] = {0xaa, 0x55, 0xff, 0x00};
const unsigned int pattern[] = BADBLOCK_PATTERNS;
int i, pat_idx;
unsigned int bb_count = 0;
blk_t got, tryout, recover_block = ~0, *blk_id;

View File

@ -30,6 +30,7 @@
#include "rufus.h"
#include "resource.h"
#include "sys_types.h"
#include "localization.h"
/*
* Globals
@ -625,7 +626,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
DWORD size;
LONGLONG size_in_sectors;
PrintStatus(0, TRUE, "Partitioning (%s)...", PartitionTypeName[partition_style]);
PrintStatus(0, TRUE, lmprintf(MSG_238, PartitionTypeName[partition_style]));
if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) {
// Go with the MS 1 MB wastage at the beginning...
@ -772,7 +773,7 @@ BOOL DeletePartitions(HANDLE hDrive)
DWORD size;
CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}};
PrintStatus(0, TRUE, "Deleting partitions...");
PrintStatus(0, TRUE, lmprintf(MSG_239));
size = sizeof(CreateDisk);
r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK,

View File

@ -43,6 +43,7 @@
#include "file.h"
#include "format.h"
#include "badblocks.h"
#include "localization.h"
/*
* Globals
@ -68,16 +69,16 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command,
switch(Command) {
case FCC_PROGRESS:
percent = (DWORD*)pData;
PrintStatus(0, FALSE, "Formatting: %d%% completed.", *percent);
PrintStatus(0, FALSE, lmprintf(MSG_217, *percent));
UpdateProgress(OP_FORMAT, 1.0f * (*percent));
break;
case FCC_STRUCTURE_PROGRESS: // No progress on quick format
PrintStatus(0, TRUE, "Creating file system: Task %d/%d completed.", ++task_number, nb_steps[fs_index]);
PrintStatus(0, TRUE, lmprintf(MSG_218, ++task_number, nb_steps[fs_index]));
format_percent += 100.0f / (1.0f * nb_steps[fs_index]);
UpdateProgress(OP_CREATE_FS, format_percent);
break;
case FCC_DONE:
PrintStatus(0, TRUE, "Creating file system: Task %d/%d completed.", nb_steps[fs_index], nb_steps[fs_index]);
PrintStatus(0, TRUE, lmprintf(MSG_218, nb_steps[fs_index], nb_steps[fs_index]));
UpdateProgress(OP_CREATE_FS, 100.0f);
if(*(BOOLEAN*)pData == FALSE) {
uprintf("Error while formatting.\n");
@ -152,7 +153,7 @@ static BOOLEAN __stdcall ChkdskCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DW
case FCC_PROGRESS:
case FCC_CHECKDISK_PROGRESS:
percent = (DWORD*)pData;
PrintStatus(0, FALSE, "NTFS Fixup: %d%% completed.", *percent);
PrintStatus(0, FALSE, lmprintf(MSG_219, *percent));
break;
case FCC_DONE:
if(*(BOOLEAN*)pData == FALSE) {
@ -365,7 +366,8 @@ static BOOL FormatFAT32(DWORD DriveIndex)
// Debug temp vars
ULONGLONG FatNeeded, ClusterCount;
PrintStatus(0, TRUE, "Formatting (Large FAT32)...");
// TODO: use another lmsg for Large FAT32
PrintStatus(0, TRUE, lmprintf(MSG_222, "Large FAT32"));
VolumeId = GetVolumeID();
// Open the drive and lock it
@ -552,7 +554,7 @@ static BOOL FormatFAT32(DWORD DriveIndex)
if (GetTickCount() > LastRefresh + 25) {
LastRefresh = GetTickCount();
format_percent = (100.0f*i)/(1.0f*(SystemAreaSize+BurstSize));
PrintStatus(0, FALSE, "Formatting: %0.1f%% completed.", format_percent);
PrintStatus(0, FALSE, lmprintf(MSG_217, format_percent));
UpdateProgress(OP_FORMAT, format_percent);
}
if (IS_ERROR(FormatStatus)) goto out; // For cancellation
@ -577,7 +579,7 @@ static BOOL FormatFAT32(DWORD DriveIndex)
}
// Must do it here, as have issues when trying to write the PBR after a remount
PrintStatus(0, TRUE, "Writing partition boot record...");
PrintStatus(0, TRUE, lmprintf(MSG_229));
if (!WritePBR(hLogicalVolume)) {
// Non fatal error, but the drive probably won't boot
uprintf("Could not write partition boot record - drive may not boot...\n");
@ -586,7 +588,7 @@ static BOOL FormatFAT32(DWORD DriveIndex)
// Set the FAT32 volume label
GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel));
ToValidLabel(wLabel, TRUE);
PrintStatus(0, TRUE, "Setting Label (This may take while)...");
PrintStatus(0, TRUE, lmprintf(MSG_221));
// Handle must be closed for SetVolumeLabel to work
safe_closehandle(hLogicalVolume);
VolumeName = GetLogicalName(DriveIndex, TRUE, TRUE);
@ -617,17 +619,16 @@ static BOOL FormatDrive(DWORD DriveIndex)
{
BOOL r = FALSE;
PF_DECL(FormatEx);
char FSType[32], format_status[64];
char FSType[32];
char *locale, *VolumeName = NULL;
WCHAR* wVolumeName = NULL;
WCHAR wFSType[32];
WCHAR wFSType[64];
WCHAR wLabel[64];
ULONG ulClusterSize;
size_t i;
GetWindowTextA(hFileSystem, FSType, ARRAYSIZE(FSType));
safe_sprintf(format_status, ARRAYSIZE(format_status), "Formatting (%s)...", FSType);
PrintStatus(0, TRUE, format_status);
GetWindowTextU(hFileSystem, FSType, ARRAYSIZE(FSType));
PrintStatus(0, TRUE, lmprintf(MSG_222, FSType));
VolumeName = GetLogicalName(DriveIndex, FALSE, TRUE);
wVolumeName = utf8_to_wchar(VolumeName);
if (wVolumeName == NULL) {
@ -689,7 +690,7 @@ static BOOL CheckDisk(char DriveLetter)
size_t i;
wDriveRoot[0] = (WCHAR)DriveLetter;
PrintStatus(0, TRUE, "NTFS Fixup (Checkdisk)...");
PrintStatus(0, TRUE, lmprintf(MSG_223));
PF_INIT_OR_OUT(Chkdsk, fmifs);
@ -781,7 +782,7 @@ static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi
uint64_t i, last_sector = DiskSize/SectorSize;
unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1);
PrintStatus(0, TRUE, "Clearing MBR/PBR/GPT structures...");
PrintStatus(0, TRUE, lmprintf(MSG_224));
if (pBuf == NULL) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY;
goto out;
@ -1166,9 +1167,8 @@ DWORD WINAPI FormatThread(LPVOID param)
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
HANDLE hLogicalVolume = INVALID_HANDLE_VALUE;
SYSTEMTIME lt;
char* guid_volume = NULL;
char *bb_msg, *guid_volume = NULL;
char drive_name[] = "?:\\";
char bb_msg[512];
char logfile[MAX_PATH], *userdir;
char wim_image[] = "?:\\sources\\install.wim";
char efi_dst[] = "?:\\efi\\boot\\bootx64.efi";
@ -1180,7 +1180,7 @@ DWORD WINAPI FormatThread(LPVOID param)
bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
use_large_fat32 = (fs == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32));
PrintStatus(0, TRUE, "Requesting disk access...\n");
PrintStatus(0, TRUE, lmprintf(MSG_225));
hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE);
if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
@ -1217,7 +1217,7 @@ DWORD WINAPI FormatThread(LPVOID param)
}
CHECK_FOR_USER_CANCEL;
PrintStatus(0, TRUE, "Analyzing existing boot records...\n");
PrintStatus(0, TRUE, lmprintf(MSG_226));
AnalyzeMBR(hPhysicalDrive);
if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) {
AnalyzePBR(hLogicalVolume);
@ -1267,19 +1267,15 @@ DWORD WINAPI FormatThread(LPVOID param)
report.num_read_errors, report.num_write_errors, report.num_corruption_errors);
r = IDOK;
if (report.bb_count) {
safe_sprintf(bb_msg, sizeof(bb_msg), "Check completed: %u bad block%s found.\n"
" %d read errors\n %d write errors\n %d corruption errors\n",
report.bb_count, (report.bb_count==1)?"":"s",
report.num_read_errors, report.num_write_errors,
bb_msg = lmprintf(MSG_011, report.num_read_errors, report.num_write_errors,
report.num_corruption_errors);
fprintf(log_fd, "%s", bb_msg);
fprintf(log_fd, bb_msg);
GetLocalTime(&lt);
fprintf(log_fd, APPLICATION_NAME " bad blocks check ended on: %04d.%02d.%02d %02d:%02d:%02d\n",
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
fclose(log_fd);
safe_sprintf(&bb_msg[strlen(bb_msg)], sizeof(bb_msg)-strlen(bb_msg)-1,
"\nA more detailed report can be found in:\n%s\n", logfile);
r = MessageBoxU(hMainDialog, bb_msg, "Bad blocks found", MB_ABORTRETRYIGNORE|MB_ICONWARNING);
r = MessageBoxU(hMainDialog, lmprintf(MSG_012, bb_msg, logfile),
lmprintf(MSG_010), MB_ABORTRETRYIGNORE|MB_ICONWARNING);
} else {
// We didn't get any errors => delete the log file
fclose(log_fd);
@ -1293,7 +1289,7 @@ DWORD WINAPI FormatThread(LPVOID param)
}
// Close the (unmounted) volume before formatting
if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) {
PrintStatus(0, TRUE, "Closing existing volume...\n");
PrintStatus(0, TRUE, lmprintf(MSG_227));
if (!CloseHandle(hLogicalVolume)) {
uprintf("Could not close volume: %s\n", WindowsErrorString());
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED;
@ -1339,7 +1335,7 @@ DWORD WINAPI FormatThread(LPVOID param)
// Thanks to Microsoft, we must fix the MBR AFTER the drive has been formatted
if (pt == PARTITION_STYLE_MBR) {
PrintStatus(0, TRUE, "Writing master boot record...");
PrintStatus(0, TRUE, lmprintf(MSG_228));
if (!WriteMBR(hPhysicalDrive)) {
if (!IS_ERROR(FormatStatus))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
@ -1386,7 +1382,7 @@ DWORD WINAPI FormatThread(LPVOID param)
}
// NB: if you unmount the logical volume here, XP will report error:
// [0x00000456] The media in the drive may have changed
PrintStatus(0, TRUE, "Writing partition boot record...");
PrintStatus(0, TRUE, lmprintf(MSG_229));
if (!WritePBR(hLogicalVolume)) {
if (!IS_ERROR(FormatStatus))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT;
@ -1415,7 +1411,7 @@ DWORD WINAPI FormatThread(LPVOID param)
if (IsChecked(IDC_BOOT)) {
if ((dt == DT_WINME) || (dt == DT_FREEDOS)) {
UpdateProgress(OP_DOS, -1.0f);
PrintStatus(0, TRUE, "Copying DOS files...");
PrintStatus(0, TRUE, lmprintf(MSG_230));
if (!ExtractDOS(drive_name)) {
if (!IS_ERROR(FormatStatus))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY;
@ -1424,7 +1420,7 @@ DWORD WINAPI FormatThread(LPVOID param)
} else if (dt == DT_ISO) {
if (iso_path != NULL) {
UpdateProgress(OP_DOS, 0.0f);
PrintStatus(0, TRUE, "Copying ISO files...");
PrintStatus(0, TRUE, lmprintf(MSG_231));
drive_name[2] = 0;
if (!ExtractISO(iso_path, drive_name, FALSE)) {
if (!IS_ERROR(FormatStatus))
@ -1433,7 +1429,7 @@ DWORD WINAPI FormatThread(LPVOID param)
}
if ((bt == BT_UEFI) && (!iso_report.has_efi) && (iso_report.has_win7_efi)) {
// TODO: (v1.4.0) check ISO with EFI only
PrintStatus(0, TRUE, "Win7 EFI boot setup (this may take a while)...");
PrintStatus(0, TRUE, lmprintf(MSG_232));
wim_image[0] = drive_name[0];
efi_dst[0] = drive_name[0];
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0;
@ -1456,7 +1452,7 @@ DWORD WINAPI FormatThread(LPVOID param)
}
}
UpdateProgress(OP_FINALIZE, -1.0f);
PrintStatus(0, TRUE, "Finalizing, please wait...");
PrintStatus(0, TRUE, lmprintf(MSG_233));
if (IsChecked(IDC_SET_ICON))
SetAutorun(drive_name);
// Issue another complete remount before we exit, to ensure we're clean

View File

@ -41,6 +41,7 @@
#include "rufus.h"
#include "msapi_utf8.h"
#include "resource.h"
#include "localization.h"
// How often should we update the progress bar (in 2K blocks) as updating
// the progress bar for every block will bring extraction to a crawl
@ -77,16 +78,15 @@ static __inline char* size_to_hr(int64_t size)
{
int suffix = 0;
static char str_size[24];
const char* sizes[] = { "", "KB", "MB", "GB", "TB" };
double hr_size = (double)size;
while ((suffix < ARRAYSIZE(sizes)) && (hr_size >= 1024.0)) {
while ((suffix < MAX_SIZE_SUFFIXES) && (hr_size >= 1024.0)) {
hr_size /= 1024.0;
suffix++;
}
if (suffix == 0) {
safe_sprintf(str_size, sizeof(str_size), " (%d bytes)", (int)hr_size);
safe_sprintf(str_size, sizeof(str_size), " (%d %s)", (int)hr_size, lmprintf(MSG_020));
} else {
safe_sprintf(str_size, sizeof(str_size), " (%0.1f %s)", hr_size, sizes[suffix]);
safe_sprintf(str_size, sizeof(str_size), " (%0.1f %s)", hr_size, lmprintf(MSG_020+suffix));
}
return str_size;
}
@ -419,7 +419,6 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
LONG progress_style;
char* tmp;
char path[64];
const char* scan_text = "Scanning ISO image...";
const char* basedir[] = { "i386", "minint" };
const char* tmp_sif = ".\\txtsetup.sif~";
iso_extension_mask_t iso_extension_mask = ISO_EXTENSION_ALL;
@ -437,14 +436,14 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
// String array of all isolinux/syslinux locations
StrArrayCreate(&config_path, 8);
// Change the Window title and static text
SetWindowTextU(hISOProgressDlg, scan_text);
SetWindowTextU(hISOFileName, scan_text);
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_202));
SetWindowTextU(hISOFileName, lmprintf(MSG_202));
// Change progress style to marquee for scanning
SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style | PBS_MARQUEE);
SendMessage(hISOProgressBar, PBM_SETMARQUEE, TRUE, 0);
} else {
uprintf("Extracting files...\n");
SetWindowTextU(hISOProgressDlg, "Copying ISO files...");
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_231));
if (total_blocks == 0) {
uprintf("Error: ISO has not been properly scanned.\n");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN);
@ -506,7 +505,7 @@ out:
iso_blocking_status = -1;
if (scan_only) {
// Remove trailing spaces from the label
for (j=(int)safe_strlen(iso_report.label)-1; ((j>=0)&&(isspace(iso_report.label[j]))); j--)
for (j=(int)safe_strlen(iso_report.label)-1; ((j>=0)&&(isspaceU(iso_report.label[j]))); j--)
iso_report.label[j] = 0;
// We use the fact that UDF_BLOCKSIZE and ISO_BLOCKSIZE are the same here
iso_report.projected_size = total_blocks * ISO_BLOCKSIZE;

View File

@ -19,16 +19,17 @@
const char* about_blurb_format =
"{\\rtf1\\ansi\n"
"{\\b\\fs20Rufus - The Reliable USB Formatting Utility}\\line\n"
"\\fs18Version %d.%d.%d (Build %d)\\line\n"
"{\\b\\fs20%s}\\line\n"
"\\fs18%s\\line\n"
"\\line\n"
"Copyright © 2011-2013 Pete Batard / Akeo\\line\n"
RUFUS_URL "\\line\n"
"%s\\line\n"
"\\line\n"
"Report bugs or request enhancements at:\\line\n"
"%s\\line\n"
"https://github.com/pbatard/rufus/issues\\line\n"
"\\line\n"
"{\\b\\fs18Additional Copyrights:}}";
"{\\b\\fs18 %s}}";
const char* additional_copyrights =
"{\\rtf1\\ansi\n"
@ -90,17 +91,15 @@ const char* additional_copyrights =
const char* update_policy =
"{\\rtf1\\ansi{\\fonttbl{\\f0\\fnil\\fcharset0 Microsoft Sans Serif;}{\\f1\\fnil\\fcharset2 Symbol;}}\n"
"\\fs16\\b Update Policy:\\b0\\line\n"
"If you choose to allow this program to check for application updates, you agree that the following information may be collected on our server(s):\\par\n"
"\\pard{\\pntext\\f1\\'B7\\tab}{\\*\\pn\\pnlvlblt\\pnf2\\pnindent0{\\pntxtb\\'B7}}\\fi-150\\li220 Your operating system's architecture and version\\par\n"
"{\\pntext\\f1\\'B7\\tab}The version of the application you use\\par\n"
"{\\pntext\\f1\\'B7\\tab}Your IP address\\line\\pard\n"
"\\fs16\\b %s\\b0\\line\n"
"%s:\\par\n"
"\\pard{\\pntext\\f1\\'B7\\tab}{\\*\\pn\\pnlvlblt\\pnf2\\pnindent0{\\pntxtb\\'B7}}\\fi-150\\li220 %s\\par\n"
"{\\pntext\\f1\\'B7\\tab}%s\\par\n"
"{\\pntext\\f1\\'B7\\tab}%s\\line\\pard\n"
"\\line\n"
"For the purpose of generating private usage statistics, we may keep the information collected, \n"
"\\b for at most a year\\b0 . However, we will not willingly disclose any of this individual data to third parties.\\line\n\\line\n"
"\\b Update Process:\\b0\\line\n"
APPLICATION_NAME " does not install or run background services, therefore update checks are performed only when the main application is running.\\line\n"
"Internet access is of course required when checking for updates.\\line\n"
"%s\\line\n\\line\n"
"\\b %s\\b0\\line\n"
"%s\\line\n"
"}";
const char* gplv3 =

368
src/localization.c Normal file
View File

@ -0,0 +1,368 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Localization functions, a.k.a. "Everybody is doing it wrong but me!"
* Copyright © 2013 Pete Batard <pete@akeo.ie>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
#ifdef _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stddef.h>
#include "rufus.h"
#include "resource.h"
#include "msapi_utf8.h"
#include "localization.h"
#include "localization_data.h"
/*
* List of supported locale commands, with their parameter syntax:
* c control ID (no space, no quotes)
* s: quoted string
* i: 32 bit signed integer
* u: 32 bit unsigned CSV list
* Remember to update the size of the array in localization.h when adding/removing elements
*/
const loc_parse parse_cmd[9] = {
// Translation name and Windows LCIDs it should apply to
{ 'l', LC_LOCALE, "ssu" }, // l "en_US" "English (US)" 0x0009,0x1009
// Base translation to add on top of (eg. "English (UK)" can be used to build on top of "English (US)"
{ 'b', LC_BASE, "s" }, // b "en_US"
// Version to use for the localization commandset and API
{ 'v', LC_VERSION, "ii" }, // v 1.0 // TODO: NOT IMPLEMENTED YET
// Translate the text control associated with an ID
{ 't', LC_TEXT, "cs" }, // t IDC_CONTROL "Translation"
// Set the section/dialog to which the next commands should apply
{ 'g', LC_GROUP, "c" }, // g IDD_DIALOG
// Resize a dialog (dx dy pixel increment)
{ 's', LC_SIZE, "cii" }, // s IDC_CONTROL +10 +10
// Move a dialog (dx dy pixed displacement)
{ 'm', LC_MOVE, "cii" }, // m IDC_CONTROL -5 0
// Set the font to use for the text controls that follow
// Use f "Default" 0 to reset the font
{ 'f', LC_FONT, "si" }, // f "MS Dialog" 10
// Set the direction to use for the text controls that follow
// 0 = Left to right, 1 = Right to left
{ 'd', LC_DIRECTION, "i" }, // d 1 // TODO: NOT IMPLEMENTED YET
};
/* Globals */
int loc_line_nr;
struct list_head locale_list = {NULL, NULL};
char *loc_filename = NULL, *embedded_loc_filename = "[embedded] rufus.loc";
/*
* Add a localization command to a dialog/section
*/
void add_dialog_command(int index, loc_cmd* lcmd)
{
if ((lcmd == NULL) || (index < 0) || (index >= ARRAYSIZE(loc_dlg))) {
uprintf("add_dialog_command: invalid parameter\n");
return;
}
list_add(&lcmd->list, &loc_dlg[index].list);
}
void free_loc_cmd(loc_cmd* lcmd)
{
if (lcmd == NULL)
return;
safe_free(lcmd->txt[0]);
safe_free(lcmd->txt[1]);
safe_free(lcmd->unum);
free(lcmd);
}
void free_dialog_list(void)
{
size_t i = 0;
loc_cmd *lcmd, *next;
for (i=0; i<ARRAYSIZE(loc_dlg); i++) {
if (list_empty(&loc_dlg[i].list))
continue;
list_for_each_entry_safe(lcmd, next, &loc_dlg[i].list, loc_cmd, list) {
list_del(&lcmd->list);
free_loc_cmd(lcmd);
}
}
}
void free_locale_list(void)
{
loc_cmd *lcmd, *next;
list_for_each_entry_safe(lcmd, next, &locale_list, loc_cmd, list) {
list_del(&lcmd->list);
free_loc_cmd(lcmd);
}
}
/*
* Init/destroy our various localization lists
*/
void init_localization(void) {
size_t i;
for (i=0; i<ARRAYSIZE(loc_dlg); i++)
list_init(&loc_dlg[i].list);
list_init(&locale_list);
}
void exit_localization(void) {
free_dialog_list();
free_locale_list();
}
/*
* Validate and store localization command data
*
* TODO: Do we need to store a revert for every action we execute here,
* or do we want to reinstantiate the dialogs?
*/
BOOL dispatch_loc_cmd(loc_cmd* lcmd)
{
size_t i;
static int dlg_index = 0;
loc_cmd* base_locale = NULL;
if (lcmd == NULL)
return FALSE;
if (lcmd->command <= LC_TEXT) {
// Any command up to LC_TEXT takes a control ID in text[0]
for (i=0; i<ARRAYSIZE(control_id); i++) {
if (safe_strcmp(lcmd->txt[0], control_id[i].name) == 0) {
lcmd->ctrl_id = control_id[i].id;
break;
}
}
if (lcmd->ctrl_id < 0) {
luprintf("unknown control '%s'\n", lcmd->txt[0]);
goto err;
}
}
switch(lcmd->command) {
// NB: For commands that take an ID, ctrl_id is always a valid index at this stage
case LC_TEXT:
case LC_MOVE:
case LC_SIZE:
add_dialog_command(dlg_index, lcmd);
break;
case LC_GROUP:
if ((lcmd->ctrl_id-IDD_DIALOG) > ARRAYSIZE(loc_dlg)) {
luprintf("'%s' is not a group ID\n", lcmd->txt[0]);
goto err;
}
dlg_index = lcmd->ctrl_id - IDD_DIALOG;
free_loc_cmd(lcmd);
break;
case LC_VERSION:
luprintf("GOT VERSION: %d.%d\n", lcmd->num[0], lcmd->num[1]);
free_loc_cmd(lcmd);
break;
case LC_BASE:
base_locale = get_locale_from_name(lcmd->txt[0]);
if (base_locale != NULL) {
uprintf("localization: using locale base '%s'", lcmd->txt[0]);
get_loc_data_file(NULL, (long)base_locale->num[0], (long)base_locale->num[1], base_locale->line_nr);
} else {
uprintf("localization: locale base '%s' not found", lcmd->txt[0]);
}
free_loc_cmd(lcmd);
break;
default:
free_loc_cmd(lcmd);
break;
}
return TRUE;
err:
free_loc_cmd(lcmd);
return FALSE;
}
/*
* Apply stored localization commands to a specific dialog
* If hDlg is NULL, apply the commands against an active Window
* TODO: if dlg_id is <0, apply all
*/
void apply_localization(int dlg_id, HWND hDlg)
{
loc_cmd* lcmd;
HWND hCtrl = NULL;
int id_start = IDD_DIALOG, id_end = IDD_DIALOG + ARRAYSIZE(loc_dlg);
LONG_PTR style;
BOOL left_to_right = FALSE;
if ((dlg_id >= id_start) && (dlg_id < id_end)) {
// If we have a valid dialog_id, just process that one dialog
id_start = dlg_id;
id_end = dlg_id + 1;
if (hDlg != NULL) {
loc_dlg[dlg_id-IDD_DIALOG].hDlg = hDlg;
}
}
for (dlg_id = id_start; dlg_id < id_end; dlg_id++) {
hDlg = loc_dlg[dlg_id-IDD_DIALOG].hDlg;
if ((!IsWindow(hDlg)) || (list_empty(&loc_dlg[dlg_id-IDD_DIALOG].list)))
continue;
// TODO: storing the messages in an array indexed on the message ID - 3000 would be faster
list_for_each_entry(lcmd, &loc_dlg[dlg_id-IDD_DIALOG].list, loc_cmd, list) {
if (lcmd->command <= LC_TEXT) { // TODO: should always be the case
if (lcmd->ctrl_id == dlg_id) {
if ((dlg_id == IDD_DIALOG) && (lcmd->txt[1] != NULL) && (lcmd->txt[1][0] != 0)) {
loc_line_nr = lcmd->line_nr;
luprint("operation forbidden (main dialog title cannot be changed)");
continue;
}
hCtrl = hDlg;
} else {
hCtrl = GetDlgItem(hDlg, lcmd->ctrl_id);
}
if (hCtrl == NULL) {
loc_line_nr = lcmd->line_nr;
luprintf("control '%s' is not part of dialog '%s'\n",
lcmd->txt[0], control_id[dlg_id-IDD_DIALOG].name);
}
}
switch(lcmd->command) {
// NB: For commands that take an ID, ctrl_id is always a valid index at this stage
case LC_TEXT:
if (hCtrl != NULL) {
if ((lcmd->txt[1] != NULL) && (lcmd->txt[1][0] != 0))
SetWindowTextU(hCtrl, lcmd->txt[1]);
if (left_to_right) {
style = GetWindowLongPtr(hCtrl, GWL_EXSTYLE);
style |= WS_EX_LAYOUTRTL; // WS_EX_RIGHT | WS_EX_RTLREADING
SetWindowLongPtr(hCtrl, GWL_EXSTYLE, style);
InvalidateRect(hCtrl, NULL, TRUE);
}
}
break;
case LC_MOVE:
if (hCtrl != NULL) {
ResizeMoveCtrl(hDlg, hCtrl, lcmd->num[0], lcmd->num[1], 0, 0);
}
break;
case LC_SIZE:
if (hCtrl != NULL) {
ResizeMoveCtrl(hDlg, hCtrl, 0, 0, lcmd->num[0], lcmd->num[1]);
}
break;
}
}
}
}
/*
* This function should be called when a localized dialog is destroyed
* NB: we can't use isWindow() against our existing HWND to avoid this call
* as handles are recycled.
*/
void reset_localization(int dlg_id)
{
loc_dlg[dlg_id-IDD_DIALOG].hDlg = NULL;
}
/*
* Produce a formatted localized message.
* Like printf, this call takes a variable number of argument, and uses
* the message ID to identify the formatted message to use.
* Uses a rolling list of buffers to allow concurrency
* TODO: use dynamic realloc'd buffer in case LOC_MESSAGE_SIZE is not enough
*/
char* lmprintf(int msg_id, ...)
{
static int buf_id = 0;
static char buf[LOC_MESSAGE_NB][LOC_MESSAGE_SIZE];
char *format = NULL;
va_list args;
loc_cmd* lcmd;
buf_id %= LOC_MESSAGE_NB;
buf[buf_id][0] = 0;
list_for_each_entry(lcmd, &loc_dlg[IDD_MESSAGES-IDD_DIALOG].list, loc_cmd, list) {
if ((lcmd->command == LC_TEXT) && (lcmd->ctrl_id == msg_id) && (lcmd->txt[1] != NULL)) {
format = lcmd->txt[1];
}
}
if (format == NULL) {
safe_sprintf(buf[buf_id], LOC_MESSAGE_SIZE-1, "MSG_%03d UNTRANSLATED", msg_id - MSG_000);
} else {
va_start(args, msg_id);
safe_vsnprintf(buf[buf_id], LOC_MESSAGE_SIZE-1, format, args);
va_end(args);
buf[buf_id][LOC_MESSAGE_SIZE-1] = '\0';
}
return buf[buf_id++];
}
/*
* These 2 functions are used to set the current locale
*/
loc_cmd* get_locale_from_lcid(int lcid)
{
loc_cmd* lcmd = NULL;
int i;
if (list_empty(&locale_list)) {
uprintf("localization: the locale list is empty!\n");
return NULL;
}
list_for_each_entry(lcmd, &locale_list, loc_cmd, list) {
for (i=0; i<lcmd->unum_size; i++) {
if (lcmd->unum[i] == lcid) {
return lcmd;
}
}
}
lcmd = list_entry(locale_list.next, loc_cmd, list);
// If we couldn't find a supported locale, just pick the first one (usually English)
uprintf("localization: could not find locale for LCID: 0x%04X. Will default to '%s'\n", lcid, lcmd->txt[0]);
return lcmd;
}
loc_cmd* get_locale_from_name(char* locale_name)
{
loc_cmd* lcmd = NULL;
if (list_empty(&locale_list)) {
uprintf("localization: the locale list is empty!\n");
return NULL;
}
list_for_each_entry(lcmd, &locale_list, loc_cmd, list) {
if (safe_strcmp(lcmd->txt[0], locale_name) == 0)
return lcmd;
}
lcmd = list_entry(locale_list.next, loc_cmd, list);
uprintf("localization: could not find locale for name '%s'. Will default to '%s'\n", locale_name, lcmd->txt[0]);
return lcmd;
}

158
src/localization.h Normal file
View File

@ -0,0 +1,158 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Localization functions, a.k.a. "Everybody is doing it wrong but me!"
* Copyright © 2013 Pete Batard <pete@akeo.ie>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stddef.h>
#pragma once
// Number of concurrent localization messages. Must be a power of 2.
#define LOC_MESSAGE_NB 8
#define LOC_MESSAGE_SIZE 2048
#define luprint(msg) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr)
#define luprintf(msg, ...) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr, __VA_ARGS__)
/*
* List handling functions (stolen from libusb)
* NB: offsetof() requires '#include <stddef.h>'
*/
struct list_head {
struct list_head *prev, *next;
};
/* Get an entry from the list
* ptr - the address of this list_head element in "type"
* type - the data type that contains "member"
* member - the list_head element in "type"
*/
#define list_entry(ptr, type, member) \
((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member)))
/* Get each entry from a list
* pos - A structure pointer has a "member" element
* head - list head
* member - the list_head element in "pos"
* type - the type of the first parameter
*/
#define list_for_each_entry(pos, head, type, member) \
for (pos = list_entry((head)->next, type, member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, type, member))
#define list_for_each_entry_safe(pos, n, head, type, member) \
for (pos = list_entry((head)->next, type, member), \
n = list_entry(pos->member.next, type, member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, type, member))
#define list_empty(entry) ((entry)->next == (entry))
static __inline void list_init(struct list_head *entry)
{
entry->prev = entry->next = entry;
}
static __inline void list_add(struct list_head *entry, struct list_head *head)
{
entry->next = head->next;
entry->prev = head;
head->next->prev = entry;
head->next = entry;
}
static __inline void list_add_tail(struct list_head *entry,
struct list_head *head)
{
entry->next = head;
entry->prev = head->prev;
head->prev->next = entry;
head->prev = entry;
}
static __inline void list_del(struct list_head *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
entry->next = entry->prev = NULL;
}
// Commands that take a control ID *MUST* be at the top
// The last command with a control ID *MUST* be LC_TEXT
enum loc_command_type {
LC_GROUP,
LC_MOVE,
LC_SIZE,
LC_TEXT, // Delimits commands that take a Control ID and commands that don't
LC_VERSION,
LC_LOCALE,
LC_BASE,
LC_FONT,
LC_DIRECTION,
};
typedef struct loc_cmd_struct {
uint8_t command;
uint8_t unum_size;
uint16_t line_nr;
int ctrl_id;
int32_t num[2];
uint32_t* unum;
char* txt[2];
struct list_head list;
} loc_cmd;
typedef struct loc_parse_struct {
char c;
enum loc_command_type cmd;
char* arg_type;
} loc_parse;
typedef struct loc_control_id_struct {
const char* name;
const int id;
} loc_control_id;
typedef struct loc_dlg_list_struct {
const int dlg_id;
HWND hDlg;
struct list_head list;
} loc_dlg_list;
extern const loc_parse parse_cmd[9];
extern struct list_head locale_list;
int loc_line_nr;
char *loc_filename, *embedded_loc_filename;
void free_loc_cmd(loc_cmd* lcmd);
BOOL dispatch_loc_cmd(loc_cmd* lcmd);
void init_localization(void);
void exit_localization(void);
void apply_localization(int dlg_id, HWND hDlg);
void reset_localization(int dlg_id);
void free_dialog_list(void);
char* lmprintf(int msg_id, ...);
BOOL get_supported_locales(const char* filename);
char* get_loc_data_file(const char* filename, long offset, long end_offset, int start_line);
void free_locale_list(void);
loc_cmd* get_locale_from_lcid(int lcid);
loc_cmd* get_locale_from_name(char* locale_name);

382
src/localization_data.h Normal file
View File

@ -0,0 +1,382 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Localization tables - autogenerated from resource.h
* Copyright © 2013 Pete Batard <pete@akeo.ie>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include "resource.h"
#include "localization.h"
#define LOC_CTRL(x) { #x, x }
#define LOC_DLG(x) { x, NULL, {NULL, NULL} }
// Control IDs
const loc_control_id control_id[] = {
// The dialog IDs must come first
LOC_CTRL(IDD_DIALOG),
LOC_CTRL(IDD_ABOUTBOX),
LOC_CTRL(IDD_NOTIFICATION),
LOC_CTRL(IDD_LICENSE),
LOC_CTRL(IDD_ISO_EXTRACT),
LOC_CTRL(IDD_LOG),
LOC_CTRL(IDD_UPDATE_POLICY),
LOC_CTRL(IDD_NEW_VERSION),
LOC_CTRL(IDD_MESSAGES),
LOC_CTRL(IDC_DEVICE),
LOC_CTRL(IDC_FILESYSTEM),
LOC_CTRL(IDC_START),
LOC_CTRL(IDC_PARTITION_TYPE),
LOC_CTRL(IDC_CLUSTERSIZE),
LOC_CTRL(IDC_STATUS),
LOC_CTRL(IDC_ABOUT),
LOC_CTRL(IDC_LABEL),
LOC_CTRL(IDC_QUICKFORMAT),
LOC_CTRL(IDC_BOOT),
LOC_CTRL(IDC_BADBLOCKS),
LOC_CTRL(IDC_PROGRESS),
LOC_CTRL(IDC_BOOTTYPE),
LOC_CTRL(IDC_NBPASSES),
LOC_CTRL(IDC_TEST),
LOC_CTRL(IDC_SELECT_ISO),
LOC_CTRL(IDC_SET_ICON),
LOC_CTRL(IDC_RUFUS_MBR),
LOC_CTRL(IDC_ISO_FILENAME),
LOC_CTRL(IDC_ISO_ABORT),
LOC_CTRL(IDC_DISK_ID),
LOC_CTRL(IDC_EXTRA_PARTITION),
LOC_CTRL(IDC_ENABLE_FIXED_DISKS),
LOC_CTRL(IDC_ABOUT_LICENSE),
LOC_CTRL(IDC_ABOUT_ICON),
LOC_CTRL(IDC_ABOUT_UPDATES),
LOC_CTRL(IDC_ABOUT_COPYRIGHTS),
LOC_CTRL(IDC_ABOUT_BLURB),
LOC_CTRL(IDC_LICENSE_TEXT),
LOC_CTRL(IDC_NOTIFICATION_ICON),
LOC_CTRL(IDC_NOTIFICATION_TEXT),
LOC_CTRL(IDC_NOTIFICATION_LINE),
LOC_CTRL(IDC_ADVANCED),
LOC_CTRL(IDS_ADVANCED_OPTIONS_GRP),
LOC_CTRL(IDC_LOG),
LOC_CTRL(IDC_LOG_EDIT),
LOC_CTRL(IDC_LOG_SAVE),
LOC_CTRL(IDC_LOG_CLEAR),
LOC_CTRL(IDC_MORE_INFO),
LOC_CTRL(IDC_POLICY),
LOC_CTRL(IDC_UPDATE_FREQUENCY),
LOC_CTRL(IDC_INCLUDE_BETAS),
LOC_CTRL(IDC_RELEASE_NOTES),
LOC_CTRL(IDC_DOWNLOAD),
LOC_CTRL(IDC_CHECK_NOW),
LOC_CTRL(IDC_WEBSITE),
LOC_CTRL(IDC_YOUR_VERSION),
LOC_CTRL(IDC_LATEST_VERSION),
LOC_CTRL(IDC_DOWNLOAD_URL),
LOC_CTRL(IDS_DEVICE_TXT),
LOC_CTRL(IDS_PARTITION_TYPE_TXT),
LOC_CTRL(IDS_FILESYSTEM_TXT),
LOC_CTRL(IDS_CLUSTERSIZE_TXT),
LOC_CTRL(IDS_LABEL_TXT),
LOC_CTRL(IDS_FORMAT_OPTIONS_GRP),
LOC_CTRL(IDS_UPDATE_SETTINGS_GRP),
LOC_CTRL(IDS_UPDATE_FREQUENCY_TXT),
LOC_CTRL(IDS_INCLUDE_BETAS_TXT),
LOC_CTRL(IDS_NEW_VERSION_AVAIL_TXT),
LOC_CTRL(IDS_NEW_VERSION_DOWNLOAD_GRP),
LOC_CTRL(IDS_NEW_VERSION_NOTES_GRP),
LOC_CTRL(IDS_CHECK_NOW_GRP),
LOC_CTRL(MSG_000),
LOC_CTRL(MSG_001),
LOC_CTRL(MSG_002),
LOC_CTRL(MSG_003),
LOC_CTRL(MSG_004),
LOC_CTRL(MSG_005),
LOC_CTRL(MSG_006),
LOC_CTRL(MSG_007),
LOC_CTRL(MSG_008),
LOC_CTRL(MSG_009),
LOC_CTRL(MSG_010),
LOC_CTRL(MSG_011),
LOC_CTRL(MSG_012),
LOC_CTRL(MSG_013),
LOC_CTRL(MSG_014),
LOC_CTRL(MSG_015),
LOC_CTRL(MSG_016),
LOC_CTRL(MSG_017),
LOC_CTRL(MSG_018),
LOC_CTRL(MSG_019),
LOC_CTRL(MSG_020),
LOC_CTRL(MSG_021),
LOC_CTRL(MSG_022),
LOC_CTRL(MSG_023),
LOC_CTRL(MSG_024),
LOC_CTRL(MSG_025),
LOC_CTRL(MSG_026),
LOC_CTRL(MSG_027),
LOC_CTRL(MSG_028),
LOC_CTRL(MSG_029),
LOC_CTRL(MSG_030),
LOC_CTRL(MSG_031),
LOC_CTRL(MSG_032),
LOC_CTRL(MSG_033),
LOC_CTRL(MSG_034),
LOC_CTRL(MSG_035),
LOC_CTRL(MSG_036),
LOC_CTRL(MSG_037),
LOC_CTRL(MSG_038),
LOC_CTRL(MSG_039),
LOC_CTRL(MSG_040),
LOC_CTRL(MSG_041),
LOC_CTRL(MSG_042),
LOC_CTRL(MSG_043),
LOC_CTRL(MSG_044),
LOC_CTRL(MSG_045),
LOC_CTRL(MSG_046),
LOC_CTRL(MSG_047),
LOC_CTRL(MSG_048),
LOC_CTRL(MSG_049),
LOC_CTRL(MSG_050),
LOC_CTRL(MSG_051),
LOC_CTRL(MSG_052),
LOC_CTRL(MSG_053),
LOC_CTRL(MSG_054),
LOC_CTRL(MSG_055),
LOC_CTRL(MSG_056),
LOC_CTRL(MSG_057),
LOC_CTRL(MSG_058),
LOC_CTRL(MSG_059),
LOC_CTRL(MSG_060),
LOC_CTRL(MSG_061),
LOC_CTRL(MSG_062),
LOC_CTRL(MSG_063),
LOC_CTRL(MSG_064),
LOC_CTRL(MSG_065),
LOC_CTRL(MSG_066),
LOC_CTRL(MSG_067),
LOC_CTRL(MSG_068),
LOC_CTRL(MSG_069),
LOC_CTRL(MSG_070),
LOC_CTRL(MSG_071),
LOC_CTRL(MSG_072),
LOC_CTRL(MSG_073),
LOC_CTRL(MSG_074),
LOC_CTRL(MSG_075),
LOC_CTRL(MSG_076),
LOC_CTRL(MSG_077),
LOC_CTRL(MSG_078),
LOC_CTRL(MSG_079),
LOC_CTRL(MSG_080),
LOC_CTRL(MSG_081),
LOC_CTRL(MSG_082),
LOC_CTRL(MSG_083),
LOC_CTRL(MSG_084),
LOC_CTRL(MSG_085),
LOC_CTRL(MSG_086),
LOC_CTRL(MSG_087),
LOC_CTRL(MSG_088),
LOC_CTRL(MSG_089),
LOC_CTRL(MSG_090),
LOC_CTRL(MSG_091),
LOC_CTRL(MSG_092),
LOC_CTRL(MSG_093),
LOC_CTRL(MSG_094),
LOC_CTRL(MSG_095),
LOC_CTRL(MSG_096),
LOC_CTRL(MSG_097),
LOC_CTRL(MSG_098),
LOC_CTRL(MSG_099),
LOC_CTRL(MSG_100),
LOC_CTRL(MSG_101),
LOC_CTRL(MSG_102),
LOC_CTRL(MSG_103),
LOC_CTRL(MSG_104),
LOC_CTRL(MSG_105),
LOC_CTRL(MSG_106),
LOC_CTRL(MSG_107),
LOC_CTRL(MSG_108),
LOC_CTRL(MSG_109),
LOC_CTRL(MSG_110),
LOC_CTRL(MSG_111),
LOC_CTRL(MSG_112),
LOC_CTRL(MSG_113),
LOC_CTRL(MSG_114),
LOC_CTRL(MSG_115),
LOC_CTRL(MSG_116),
LOC_CTRL(MSG_117),
LOC_CTRL(MSG_118),
LOC_CTRL(MSG_119),
LOC_CTRL(MSG_120),
LOC_CTRL(MSG_121),
LOC_CTRL(MSG_122),
LOC_CTRL(MSG_123),
LOC_CTRL(MSG_124),
LOC_CTRL(MSG_125),
LOC_CTRL(MSG_126),
LOC_CTRL(MSG_127),
LOC_CTRL(MSG_128),
LOC_CTRL(MSG_129),
LOC_CTRL(MSG_130),
LOC_CTRL(MSG_131),
LOC_CTRL(MSG_132),
LOC_CTRL(MSG_133),
LOC_CTRL(MSG_134),
LOC_CTRL(MSG_135),
LOC_CTRL(MSG_136),
LOC_CTRL(MSG_137),
LOC_CTRL(MSG_138),
LOC_CTRL(MSG_139),
LOC_CTRL(MSG_140),
LOC_CTRL(MSG_141),
LOC_CTRL(MSG_142),
LOC_CTRL(MSG_143),
LOC_CTRL(MSG_144),
LOC_CTRL(MSG_145),
LOC_CTRL(MSG_146),
LOC_CTRL(MSG_147),
LOC_CTRL(MSG_148),
LOC_CTRL(MSG_149),
LOC_CTRL(MSG_150),
LOC_CTRL(MSG_151),
LOC_CTRL(MSG_152),
LOC_CTRL(MSG_153),
LOC_CTRL(MSG_154),
LOC_CTRL(MSG_155),
LOC_CTRL(MSG_156),
LOC_CTRL(MSG_157),
LOC_CTRL(MSG_158),
LOC_CTRL(MSG_159),
LOC_CTRL(MSG_160),
LOC_CTRL(MSG_161),
LOC_CTRL(MSG_162),
LOC_CTRL(MSG_163),
LOC_CTRL(MSG_164),
LOC_CTRL(MSG_165),
LOC_CTRL(MSG_166),
LOC_CTRL(MSG_167),
LOC_CTRL(MSG_168),
LOC_CTRL(MSG_169),
LOC_CTRL(MSG_170),
LOC_CTRL(MSG_171),
LOC_CTRL(MSG_172),
LOC_CTRL(MSG_173),
LOC_CTRL(MSG_174),
LOC_CTRL(MSG_175),
LOC_CTRL(MSG_176),
LOC_CTRL(MSG_177),
LOC_CTRL(MSG_178),
LOC_CTRL(MSG_179),
LOC_CTRL(MSG_180),
LOC_CTRL(MSG_181),
LOC_CTRL(MSG_182),
LOC_CTRL(MSG_183),
LOC_CTRL(MSG_184),
LOC_CTRL(MSG_185),
LOC_CTRL(MSG_186),
LOC_CTRL(MSG_187),
LOC_CTRL(MSG_188),
LOC_CTRL(MSG_189),
LOC_CTRL(MSG_190),
LOC_CTRL(MSG_191),
LOC_CTRL(MSG_192),
LOC_CTRL(MSG_193),
LOC_CTRL(MSG_194),
LOC_CTRL(MSG_195),
LOC_CTRL(MSG_196),
LOC_CTRL(MSG_197),
LOC_CTRL(MSG_198),
LOC_CTRL(MSG_199),
LOC_CTRL(MSG_200),
LOC_CTRL(MSG_201),
LOC_CTRL(MSG_202),
LOC_CTRL(MSG_203),
LOC_CTRL(MSG_204),
LOC_CTRL(MSG_205),
LOC_CTRL(MSG_206),
LOC_CTRL(MSG_207),
LOC_CTRL(MSG_208),
LOC_CTRL(MSG_209),
LOC_CTRL(MSG_210),
LOC_CTRL(MSG_211),
LOC_CTRL(MSG_212),
LOC_CTRL(MSG_213),
LOC_CTRL(MSG_214),
LOC_CTRL(MSG_215),
LOC_CTRL(MSG_216),
LOC_CTRL(MSG_217),
LOC_CTRL(MSG_218),
LOC_CTRL(MSG_219),
LOC_CTRL(MSG_220),
LOC_CTRL(MSG_221),
LOC_CTRL(MSG_222),
LOC_CTRL(MSG_223),
LOC_CTRL(MSG_224),
LOC_CTRL(MSG_225),
LOC_CTRL(MSG_226),
LOC_CTRL(MSG_227),
LOC_CTRL(MSG_228),
LOC_CTRL(MSG_229),
LOC_CTRL(MSG_230),
LOC_CTRL(MSG_231),
LOC_CTRL(MSG_232),
LOC_CTRL(MSG_233),
LOC_CTRL(MSG_234),
LOC_CTRL(MSG_235),
LOC_CTRL(MSG_236),
LOC_CTRL(MSG_237),
LOC_CTRL(MSG_238),
LOC_CTRL(MSG_239),
LOC_CTRL(MSG_240),
LOC_CTRL(MSG_241),
LOC_CTRL(MSG_242),
LOC_CTRL(MSG_243),
LOC_CTRL(MSG_244),
LOC_CTRL(MSG_245),
LOC_CTRL(MSG_246),
LOC_CTRL(MSG_247),
LOC_CTRL(MSG_248),
LOC_CTRL(MSG_249),
LOC_CTRL(MSG_250),
LOC_CTRL(MSG_251),
LOC_CTRL(MSG_252),
LOC_CTRL(MSG_253),
LOC_CTRL(MSG_254),
LOC_CTRL(MSG_255),
LOC_CTRL(MSG_256),
LOC_CTRL(MSG_257),
LOC_CTRL(MSG_258),
LOC_CTRL(IDOK),
LOC_CTRL(IDCANCEL),
LOC_CTRL(IDABORT),
LOC_CTRL(IDRETRY),
LOC_CTRL(IDIGNORE),
LOC_CTRL(IDYES),
LOC_CTRL(IDNO),
LOC_CTRL(IDCLOSE),
LOC_CTRL(IDHELP),
};
// Dialog data
loc_dlg_list loc_dlg[] = {
LOC_DLG(IDD_DIALOG),
LOC_DLG(IDD_ABOUTBOX),
LOC_DLG(IDD_NOTIFICATION),
LOC_DLG(IDD_LICENSE),
LOC_DLG(IDD_ISO_EXTRACT),
LOC_DLG(IDD_LOG),
LOC_DLG(IDD_UPDATE_POLICY),
LOC_DLG(IDD_NEW_VERSION),
LOC_DLG(IDD_MESSAGES),
};

89
src/localization_data.sh Normal file
View File

@ -0,0 +1,89 @@
#!/bin/sh
echo This file recreates localization_data.c according resource.h
echo
# check that sed are available
type -P sed &>/dev/null || { echo "sed command not found. Aborting." >&2; exit 1; }
# Create the first sed command file
cat > cmd.sed <<\_EOF
# Insert header
1i /*\
* Rufus: The Reliable USB Formatting Utility\
* Localization tables - autogenerated from resource.h\
* Copyright © 2013 Pete Batard <pete@akeo.ie>\
*\
* 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 <http://www.gnu.org/licenses/>.\
*/\
\
#include <windows.h>\
#include "resource.h"\
#include "localization.h"\
\
#define LOC_CTRL(x) { #x, x }\
#define LOC_DLG(x) { x, NULL, {NULL, NULL} }\
\
// Control IDs\
const loc_control_id control_id[] = {\
// The dialog IDs must come first
# Add the control entries - must be in IDD_, IDC_, IDS_ or MSG_
s/^#define \([I|M][D|S][D|C|S|G]_[^ ]*\) .*/\ LOC_CTRL(\1),/
# Add standard IDs from windows.h and close table
$a\
LOC_CTRL(IDOK),\
LOC_CTRL(IDCANCEL),\
LOC_CTRL(IDABORT),\
LOC_CTRL(IDRETRY),\
LOC_CTRL(IDIGNORE),\
LOC_CTRL(IDYES),\
LOC_CTRL(IDNO),\
LOC_CTRL(IDCLOSE),\
LOC_CTRL(IDHELP),\
\};\
# Remove everything else
/^[#|\/]/d
/^$/d
_EOF
# Run first part
sed -f cmd.sed resource.h > localization_data.h
# Create the second sed command file
cat > cmd.sed <<\_EOF
# Insert dialog table header
1i // Dialog data\
loc_dlg_list loc_dlg[] = {
# Add the dialog entries - must start with IDD_
s/^#define \(IDD_[^ ]*\) .*/\ LOC_DLG(\1),/
# Close the table
$a\
};
# Remove everything else
/^[#|\/]/d
/^$/d
_EOF
# Run second part
sed -f cmd.sed resource.h >> localization_data.h
rm cmd.sed
echo Done.

View File

@ -1,6 +1,7 @@
/*
* MSAPI_UTF8: Common API calls using UTF-8 strings
* Compensating for what Microsoft should have done a long long time ago.
* Also see http://utf8everywhere.org/
*
* Copyright © 2010-2013 Pete Batard <pete@akeo.ie>
*
@ -53,6 +54,15 @@ extern "C" {
_ms_wlvi.pszText = utf8_to_wchar(pszText_); \
SNDMSG((hwndLV),LVM_SETITEMTEXTW,(WPARAM)(i),(LPARAM)&_ms_wlvi); sfree(_ms_wlvi.pszText);}
// Never ever use isdigit() or isspace(), etc. on UTF-8 strings!
// These calls take an int and char is signed so MS compilers will produce an assert error on anything that's > 0x80
#define isasciiU(c) isascii((unsigned char)(c))
#define iscntrlU(c) iscntrl((unsigned char)(c))
#define isdigitU(c) isdigit((unsigned char)(c))
#define isspaceU(c) isspace((unsigned char)(c))
#define isxdigitU(c) isxdigit((unsigned char)(c))
// NB: other issomething() calls are not implemented as they may require multibyte UTF-8 sequences to be converted
#define sfree(p) do {if (p != NULL) {free((void*)(p)); p = NULL;}} while(0)
#define wconvert(p) wchar_t* w ## p = utf8_to_wchar(p)
#define walloc(p, size) wchar_t* w ## p = (wchar_t*)calloc(size, sizeof(wchar_t))
@ -354,6 +364,38 @@ static __inline DWORD GetCurrentDirectoryU(DWORD nBufferLength, char* lpBuffer)
return ret;
}
static __inline DWORD GetTempPathU(DWORD nBufferLength, char* lpBuffer)
{
DWORD ret = 0, err = ERROR_INVALID_DATA;
walloc(lpBuffer, nBufferLength);
ret = GetTempPathW(nBufferLength, wlpBuffer);
err = GetLastError();
if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpBuffer, lpBuffer, nBufferLength)) == 0)) {
err = GetLastError();
}
wfree(lpBuffer);
SetLastError(err);
return ret;
}
static __inline DWORD GetTempFileNameU(char* lpPathName, char* lpPrefixString, UINT uUnique, char* lpTempFileName)
{
DWORD ret = 0, err = ERROR_INVALID_DATA;
wconvert(lpPathName);
wconvert(lpPrefixString);
walloc(lpTempFileName, MAX_PATH);
ret =GetTempFileNameW(wlpPathName, wlpPrefixString, uUnique, wlpTempFileName);
err = GetLastError();
if ((ret != 0) && ((ret = wchar_to_utf8_no_alloc(wlpTempFileName, lpTempFileName, MAX_PATH)) == 0)) {
err = GetLastError();
}
wfree(lpTempFileName);
wfree(lpPrefixString);
wfree(lpPathName);
SetLastError(err);
return ret;
}
static __inline DWORD GetModuleFileNameU(HMODULE hModule, char* lpFilename, DWORD nSize)
{
DWORD ret = 0, err = ERROR_INVALID_DATA;

View File

@ -34,6 +34,7 @@
#include "rufus.h"
#include "registry.h"
#include "resource.h"
#include "localization.h"
/* Maximum download chunk size, in bytes */
#define DOWNLOAD_BUFFER_SIZE 10240
@ -89,6 +90,7 @@ const char* WinInetErrorString(void)
if ((error_code < INTERNET_ERROR_BASE) || (error_code > INTERNET_ERROR_LAST))
return WindowsErrorString();
// TODO: These should be localized on an ad-hoc basis
switch(error_code) {
case ERROR_INTERNET_OUT_OF_HANDLES:
return "No more handles could be generated at this time.";
@ -263,7 +265,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
SendMessage(hProgressDialog, UM_ISO_INIT, 0, 0);
}
PrintStatus(0, FALSE, "Downloading %s: Connecting...\n", file);
PrintStatus(0, FALSE, lmprintf(MSG_240, file));
uprintf("Downloading %s from %s\n", file, url);
if (!InternetCrackUrlA(url, (DWORD)safe_strlen(url), 0, &UrlParts)) {
@ -340,7 +342,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog)
break;
dwSize += dwDownloaded;
SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize)/(1.0f*dwTotalSize))), 0);
PrintStatus(0, FALSE, "Downloading: %0.1f%%\n", (100.0f*dwSize)/(1.0f*dwTotalSize));
PrintStatus(0, FALSE, lmprintf(MSG_241, (100.0f*dwSize)/(1.0f*dwTotalSize)));
if (fwrite(buf, 1, dwDownloaded, fd) != dwDownloaded) {
uprintf("Error writing file '%s': %s\n", file, WinInetErrorString());
goto out;
@ -362,10 +364,10 @@ out:
if (fd != NULL) fclose(fd);
if (!r) {
_unlink(file);
PrintStatus(0, FALSE, "Failed to download file.");
PrintStatus(0, FALSE, lmprintf(MSG_242));
SetLastError(error_code);
MessageBoxA(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus):WinInetErrorString(),
"File download", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus):WinInetErrorString(),
lmprintf(MSG_044), MB_OK|MB_ICONERROR);
}
if (hRequest) InternetCloseHandle(hRequest);
if (hConnection) InternetCloseHandle(hConnection);
@ -456,7 +458,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
}
}
PrintStatus(3000, TRUE, "Checking for " APPLICATION_NAME " updates...\n");
PrintStatus(3000, TRUE, lmprintf(MSG_243));
status++; // 1
if (!GetVersionExA(&os_version)) {
@ -600,15 +602,14 @@ out:
if (hSession) InternetCloseHandle(hSession);
switch(status) {
case 1:
PrintStatus(3000, TRUE, "Updates: Unable to connect to the internet.\n");
PrintStatus(3000, TRUE, lmprintf(MSG_244));
break;
case 2:
PrintStatus(3000, TRUE, "Updates: Unable to access version data.\n");
PrintStatus(3000, TRUE, lmprintf(MSG_245));
break;
case 3:
case 4:
PrintStatus(3000, FALSE, "%s new version of " APPLICATION_NAME " %s\n",
found_new_version?"A":"No", found_new_version?"is available!":"was found.");
PrintStatus(3000, FALSE, lmprintf(found_new_version?MSG_246:MSG_247));
default:
break;
}

View File

@ -33,13 +33,415 @@
#include "rufus.h"
#include "msapi_utf8.h"
#include "localization.h"
// Parse a line of UTF-16 text and return the data if it matches the 'token'
// The parsed line is of the form: [ ]token[ ]=[ ]["]data["][ ] and is
// modified by the parser
static const char space[] = " \t";
static const wchar_t wspace[] = L" \t";
/*
* Fill a localization command buffer by parsing the line arguments
* The command is allocated and must be freed (by calling free_loc_cmd)
*/
static loc_cmd* get_loc_cmd(char c, char* line) {
size_t i, j, k, l, r, ti = 0, ii = 0;
char *endptr, *expected_endptr, *token;
loc_cmd* lcmd = NULL;
for (j=0; j<ARRAYSIZE(parse_cmd); j++) {
if (c == parse_cmd[j].c)
break;
}
if (j >= ARRAYSIZE(parse_cmd)) {
luprint("unknown command");
return NULL;
}
lcmd = (loc_cmd*)calloc(sizeof(loc_cmd), 1);
if (lcmd == NULL) {
luprint("could not allocate command");
return NULL;
}
lcmd->ctrl_id = -1;
lcmd->command = parse_cmd[j].cmd;
lcmd->line_nr = (uint16_t)loc_line_nr;
i = 0;
for (k = 0; parse_cmd[j].arg_type[k] != 0; k++) {
// Skip leading spaces
i += strspn(&line[i], space);
r = i;
if (line[i] == 0) {
luprintf("missing parameter for command '%c'", parse_cmd[j].c);
goto err;
}
switch(parse_cmd[j].arg_type[k]) {
case 's': // quoted string
// search leading quote
if (line[i++] != '"') {
luprint("no start quote");
goto err;
}
r = i;
// locate ending quote
while ((line[i] != 0) && ((line[i] != '"') || ((line[i] == '"') && (line[i-1] == '\\')))) {
if ((line[i] == '"') && (line[i-1] == '\\')) {
strcpy(&line[i-1], &line[i]);
} else {
i++;
}
}
if (line[i] == 0) {
luprint("no end quote");
goto err;
}
line[i++] = 0;
lcmd->txt[ti++] = safe_strdup(&line[r]);
break;
case 'c': // control ID (single word)
while ((line[i] != 0) && (line[i] != space[0]) && (line[i] != space[1]))
i++;
if (line[i] != 0)
line[i++] = 0;
lcmd->txt[ti++] = safe_strdup(&line[r]);
break;
case 'i': // 32 bit signed integer
// allow commas or dots between values
if ((line[i] == ',') || (line[i] == '.')) {
i += strspn(&line[i+1], space);
r = i;
}
while ((line[i] != 0) && (line[i] != space[0]) && (line[i] != space[1])
&& (line[i] != ',') && (line[i] != '.'))
i++;
expected_endptr = &line[i];
if (line[i] != 0)
line[i++] = 0;
lcmd->num[ii++] = (int32_t)strtol(&line[r], &endptr, 0);
if (endptr != expected_endptr) {
luprint("invalid integer");
goto err;
}
break;
case 'u': // comma separated list of unsigned integers (to end of line)
// count the number of commas
lcmd->unum_size = 1;
for (l=i; line[l] != 0; l++) {
if (line[l] == ',')
lcmd->unum_size++;
}
lcmd->unum = (uint32_t*)malloc(lcmd->unum_size * sizeof(uint32_t));
token = strtok(&line[i], ",");
for (l=0; (l<lcmd->unum_size) && (token != NULL); l++) {
lcmd->unum[l] = (int32_t)strtol(token, &endptr, 0);
token = strtok(NULL, ",");
}
if ((token != NULL) || (l != lcmd->unum_size)) {
luprint("internal error (unexpected number of numeric values)");
goto err;
}
break;
default:
uprintf("localization: unhandled arg_type '%c'\n", parse_cmd[j].arg_type[k]);
goto err;
}
}
return lcmd;
err:
free_loc_cmd(lcmd);
return NULL;
}
/*
* Parse an UTF-8 localization command line
*/
static void get_loc_data_line(char* line)
{
size_t i;
loc_cmd* lcmd = NULL;
char t;
if ((line == NULL) || (line[0] == 0))
return;
// Skip leading spaces
i = strspn(line, space);
// Read token (NUL character will be read if EOL)
t = line[i++];
if (t == '#') // Comment
return;
if ((t == 0) || ((line[i] != space[0]) && (line[i] != space[1]))) {
luprintf("syntax error: '%s'", line);
return;
}
lcmd = get_loc_cmd(t, &line[i]);
if ((lcmd != NULL) && (lcmd->command != LC_LOCALE))
// TODO: check return value?
dispatch_loc_cmd(lcmd);
else
free_loc_cmd(lcmd);
}
/*
* Open a localization file and store its file name, with special case
* when dealing with the embedded loc file.
*/
FILE* open_loc_file(const char* filename)
{
FILE* fd = NULL;
wchar_t *wfilename = NULL;
const char* tmp_ext = ".tmp";
if (filename == NULL)
return NULL;
if (loc_filename != embedded_loc_filename) {
safe_free(loc_filename);
}
if (safe_strcmp(tmp_ext, &filename[safe_strlen(filename)-4]) == 0) {
loc_filename = embedded_loc_filename;
} else {
loc_filename = safe_strdup(filename);
}
wfilename = utf8_to_wchar(filename);
if (wfilename == NULL) {
uprintf("localization: could not convert '%s' filename to UTF-16\n", filename);
goto out;
}
fd = _wfopen(wfilename, L"r");
if (fd == NULL) {
uprintf("localization: could not open '%s'\n", filename);
}
out:
safe_free(wfilename);
return fd;
}
/*
* Parse a localization file, to construct the list of available locales.
* The locale file must be UTF-8 with NO BOM.
*/
BOOL get_supported_locales(const char* filename)
{
FILE* fd = NULL;
BOOL r = FALSE;
char line[1024];
size_t i;
loc_cmd *lcmd = NULL, *last_lcmd = NULL;
long end_of_block;
fd = open_loc_file(filename);
if (fd == NULL)
goto out;
loc_line_nr = 0;
line[0] = 0;
free_locale_list();
do {
// adjust the last block
end_of_block = ftell(fd);
if (fgets(line, sizeof(line), fd) == NULL)
break;
loc_line_nr++;
// Skip leading spaces
i = strspn(line, space);
if (line[i] != 'l')
continue;
// line[i] is not NUL so i+1 is safe to access
lcmd = get_loc_cmd(line[i], &line[i+1]);
if ((lcmd == NULL) || (lcmd->command != LC_LOCALE)) {
free_loc_cmd(lcmd);
continue;
}
// we use num[0] and num[1] as block delimiter index for this locale in the file
if (last_lcmd != NULL) {
last_lcmd->num[1] = (int32_t)end_of_block;
}
lcmd->num[0] = (int32_t)ftell(fd);
// Add our locale command to the locale list
list_add_tail(&lcmd->list, &locale_list);
uprintf("localization: found locale '%s'\n", lcmd->txt[0]);
last_lcmd = lcmd;
} while (1);
if (last_lcmd != NULL)
last_lcmd->num[1] = (int32_t)ftell(fd);
r = !list_empty(&locale_list);
if (r == FALSE)
uprintf("localization: '%s' contains no locale sections\n", filename);
out:
if (fd != NULL)
fclose(fd);
return r;
}
/*
* Parse a locale section in a localization file (UTF-8, no BOM)
* NB: this call is reentrant for the "base" command support
*/
char* get_loc_data_file(const char* filename, long offset, long end_offset, int start_line)
{
size_t bufsize = 1024;
static FILE* fd = NULL;
char *ret = NULL, *buf = NULL;
size_t i = 0;
int r = 0, line_nr_incr = 1;
int c = 0, eol_char = 0;
int old_loc_line_nr;
BOOL eol = FALSE, escape_sequence = FALSE, reentrant = (fd != NULL);
long cur_offset = -1;
if (reentrant) {
// Called, from a 'b' command - no need to reopen the file,
// just save the current offset and current line number
cur_offset = ftell(fd);
old_loc_line_nr = loc_line_nr;
} else {
if ((filename == NULL) || (filename[0] == 0))
return NULL;
free_dialog_list();
fd = open_loc_file(filename);
if (fd == NULL)
goto out;
}
loc_line_nr = start_line;
buf = (char*) malloc(bufsize);
if (buf == NULL) {
uprintf("localization: could not allocate line buffer\n");
goto out;
}
fseek(fd, offset, SEEK_SET);
do { // custom readline handling for string collation, realloc, line numbers, etc.
c = getc(fd);
switch(c) {
case EOF:
buf[i] = 0;
if (!eol)
loc_line_nr += line_nr_incr;
get_loc_data_line(buf);
goto out;
case '\r':
case '\n':
if (escape_sequence) {
escape_sequence = FALSE;
break;
}
// This assumes that the EOL sequence is always the same throughout the file
if (eol_char == 0)
eol_char = c;
if (c == eol_char) {
if (eol) {
line_nr_incr++;
} else {
loc_line_nr += line_nr_incr;
line_nr_incr = 1;
}
}
buf[i] = 0;
if (!eol) {
// Strip trailing spaces (for string collation)
for (r = ((int)i)-1; (r>0) && ((buf[r]==space[0])||(buf[r]==space[1])); r--);
if (r < 0)
r = 0;
eol = TRUE;
}
break;
case ' ':
case '\t':
if (escape_sequence) {
escape_sequence = FALSE;
break;
}
if (!eol) {
buf[i++] = (char)c;
}
break;
case '\\':
if (!escape_sequence) {
escape_sequence = TRUE;
break;
}
// fall through on escape sequence
default:
if (escape_sequence) {
switch (c) {
case 'n': // \n -> CRLF
buf[i++] = '\r';
buf[i++] = '\n';
break;
case '"': // \" carried as is
buf[i++] = '\\';
buf[i++] = '"';
break;
case '\\':
buf[i++] = '\\';
break;
default: // ignore any other escape sequence
break;
}
escape_sequence = FALSE;
} else {
// Collate multiline strings
if ((eol) && (c == '"') && (buf[r] == '"')) {
i = r;
eol = FALSE;
break;
}
if (eol) {
get_loc_data_line(buf);
eol = FALSE;
i = 0;
r = 0;
}
buf[i++] = (char)c;
}
break;
}
if (ftell(fd) > end_offset)
goto out;
// Have at least 2 chars extra, for \r\n sequences
if (i >= bufsize-2) {
bufsize *= 2;
if (bufsize > 32768) {
uprintf("localization: requested line buffer is larger than 32K!\n");
goto out;
}
buf = (char*) _reallocf(buf, bufsize);
if (buf == NULL) {
uprintf("localization: could not grow line buffer\n");
goto out;
}
}
} while(1);
out:
// Don't close on a reentrant call
if (reentrant) {
fseek(fd, cur_offset, SEEK_SET);
loc_line_nr = old_loc_line_nr;
} else if (fd != NULL) {
fclose(fd);
fd = NULL;
}
safe_free(buf);
return ret;
}
/*
* Parse a line of UTF-16 text and return the data if it matches the 'token'
* The parsed line is of the form: [ ]token[ ]=[ ]["]data["][ ] and is
* modified by the parser
*/
static wchar_t* get_token_data_line(const wchar_t* wtoken, wchar_t* wline)
{
const wchar_t wspace[] = L" \t"; // The only whitespaces we recognize as such
size_t i, r;
BOOLEAN quoteth = FALSE;
@ -90,8 +492,10 @@ static wchar_t* get_token_data_line(const wchar_t* wtoken, wchar_t* wline)
return (wline[r] == 0)?NULL:&wline[r];
}
// Parse a file (ANSI or UTF-8 or UTF-16) and return the data for the first occurrence of 'token'
// The returned string is UTF-8 and MUST be freed by the caller
/*
* Parse a file (ANSI or UTF-8 or UTF-16) and return the data for the first occurrence of 'token'
* The returned string is UTF-8 and MUST be freed by the caller
*/
char* get_token_data_file(const char* token, const char* filename)
{
wchar_t *wtoken = NULL, *wdata= NULL, *wfilename = NULL;
@ -135,8 +539,10 @@ out:
return ret;
}
// Parse a buffer (ANSI or UTF-8) and return the data for the 'n'th occurrence of 'token'
// The returned string is UTF-8 and MUST be freed by the caller
/*
* Parse a buffer (ANSI or UTF-8) and return the data for the 'n'th occurrence of 'token'
* The returned string is UTF-8 and MUST be freed by the caller
*/
char* get_token_data_buffer(const char* token, unsigned int n, const char* buffer, size_t buffer_size)
{
unsigned int j, curly_count;
@ -199,10 +605,12 @@ static __inline char* get_sanitized_token_data_buffer(const char* token, unsigne
return data;
}
// Parse an update data file and populates a rufus_update structure.
// NB: since this is remote data, and we're running elevated, it *IS* considered
// potentially malicious, even if it comes from a supposedly trusted server.
// len should be the size of the buffer, including the zero terminator
/*
* Parse an update data file and populates a rufus_update structure.
* NB: since this is remote data, and we're running elevated, it *IS* considered
* potentially malicious, even if it comes from a supposedly trusted server.
* len should be the size of the buffer, including the zero terminator
*/
void parse_update(char* buf, size_t len)
{
size_t i;
@ -249,13 +657,14 @@ void parse_update(char* buf, size_t len)
update.release_notes = get_sanitized_token_data_buffer("release_notes", 1, buf, len);
}
// Insert entry 'data' under section 'section' of a config file
// Section must include the relevant delimitors (eg '[', ']') if needed
/*
* Insert entry 'data' under section 'section' of a config file
* Section must include the relevant delimitors (eg '[', ']') if needed
*/
char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix)
{
const wchar_t* outmode[] = { L"w", L"w, ccs=UTF-8", L"w, ccs=UTF-16LE" };
wchar_t *wsection = NULL, *wfilename = NULL, *wtmpname = NULL, *wdata = NULL, bom = 0;
wchar_t wspace[] = L" \t";
wchar_t buf[1024];
FILE *fd_in = NULL, *fd_out = NULL;
size_t i, size;
@ -316,7 +725,7 @@ char* insert_section_data(const char* filename, const char* section, const char*
fd_out = _wfopen(wtmpname, outmode[mode]);
if (fd_out == NULL) {
uprintf("Could not open temporary output file %s~\n", filename);
uprintf("Could not open temporary output file '%s~'\n", filename);
goto out;
}
@ -360,7 +769,7 @@ out:
fclose(fd_in);
fclose(fd_out);
} else {
uprintf("Could not write %s - original file has been left unmodifiedn", filename);
uprintf("Could not write '%s' - original file has been left unmodified\n", filename);
ret = NULL;
if (fd_in != NULL) fclose(fd_in);
if (fd_out != NULL) fclose(fd_out);
@ -375,15 +784,16 @@ out:
return ret;
}
// Search for a specific 'src' substring data for all occurrences of 'token', and replace
// it with 'rep'. File can be ANSI or UNICODE and is overwritten. Parameters are UTF-8.
// The parsed line is of the form: [ ]token[ ]data
// Returns a pointer to rep if replacement occurred, NULL otherwise
/*
* Search for a specific 'src' substring data for all occurrences of 'token', and replace
* it with 'rep'. File can be ANSI or UNICODE and is overwritten. Parameters are UTF-8.
* The parsed line is of the form: [ ]token[ ]data
* Returns a pointer to rep if replacement occurred, NULL otherwise
*/
char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix)
{
const wchar_t* outmode[] = { L"w", L"w, ccs=UTF-8", L"w, ccs=UTF-16LE" };
wchar_t *wtoken = NULL, *wfilename = NULL, *wtmpname = NULL, *wsrc = NULL, *wrep = NULL, bom = 0;
wchar_t wspace[] = L" \t";
wchar_t buf[1024], *torep;
FILE *fd_in = NULL, *fd_out = NULL;
size_t i, size;
@ -451,7 +861,7 @@ char* replace_in_token_data(const char* filename, const char* token, const char*
fd_out = _wfopen(wtmpname, outmode[mode]);
if (fd_out == NULL) {
uprintf("Could not open temporary output file %s~\n", filename);
uprintf("Could not open temporary output file '%s~'\n", filename);
goto out;
}
@ -506,7 +916,7 @@ out:
fclose(fd_in);
fclose(fd_out);
} else {
uprintf("Could not write %s - original file has been left unmodified.\n", filename);
uprintf("Could not write '%s' - original file has been left unmodified.\n", filename);
ret = NULL;
if (fd_in != NULL) fclose(fd_in);
if (fd_out != NULL) fclose(fd_out);

View File

@ -3,17 +3,17 @@
// Used by rufus.rc
//
#define IDD_DIALOG 101
#define IDI_ICON 102
#define IDD_ABOUTBOX 103
#define IDD_NOTIFICATION 104
#define IDD_LICENSE 105
#define IDD_ISO_EXTRACT 106
#define IDD_LOG 107
#define IDS_VERSION 108
#define IDI_UP 109
#define IDI_DOWN 110
#define IDD_UPDATE_POLICY 111
#define IDD_NEW_VERSION 112
#define IDD_ABOUTBOX 102
#define IDD_NOTIFICATION 103
#define IDD_LICENSE 104
#define IDD_ISO_EXTRACT 105
#define IDD_LOG 106
#define IDD_UPDATE_POLICY 107
#define IDD_NEW_VERSION 108
#define IDD_MESSAGES 109
#define IDI_ICON 110
#define IDI_UP 111
#define IDI_DOWN 112
#define IDR_BR_MBR_BIN 200
#define IDR_FD_COMMAND_COM 300
#define IDR_FD_KERNEL_SYS 301
@ -46,10 +46,11 @@
#define IDR_SL_LDLINUX_V4_SYS 401
#define IDR_SL_LDLINUX_V5_BSS 402
#define IDR_SL_LDLINUX_V5_SYS 403
#define IDR_LC_RUFUS_LOC 500
#define IDC_DEVICE 1001
#define IDC_FILESYSTEM 1002
#define IDC_START 1003
#define IDC_PARTITION_SCHEME 1004
#define IDC_PARTITION_TYPE 1004
#define IDC_CLUSTERSIZE 1005
#define IDC_STATUS 1006
#define IDC_ABOUT 1007
@ -79,7 +80,7 @@
#define IDC_NOTIFICATION_TEXT 1041
#define IDC_NOTIFICATION_LINE 1042
#define IDC_ADVANCED 1043
#define IDC_ADVANCED_GROUP 1044
#define IDS_ADVANCED_OPTIONS_GRP 1044
#define IDC_LOG 1045
#define IDC_LOG_EDIT 1050
#define IDC_LOG_SAVE 1051
@ -95,15 +96,287 @@
#define IDC_YOUR_VERSION 1068
#define IDC_LATEST_VERSION 1069
#define IDC_DOWNLOAD_URL 1070
#define IDS_DEVICE_TXT 2000
#define IDS_PARTITION_TYPE_TXT 2001
#define IDS_FILESYSTEM_TXT 2002
#define IDS_CLUSTERSIZE_TXT 2003
#define IDS_LABEL_TXT 2004
#define IDS_FORMAT_OPTIONS_GRP 2005
#define IDS_UPDATE_SETTINGS_GRP 2006
#define IDS_UPDATE_FREQUENCY_TXT 2007
#define IDS_INCLUDE_BETAS_TXT 2008
#define IDS_NEW_VERSION_AVAIL_TXT 2009
#define IDS_NEW_VERSION_DOWNLOAD_GRP 2010
#define IDS_NEW_VERSION_NOTES_GRP 2011
#define IDS_CHECK_NOW_GRP 2012
#define MSG_000 3000
#define MSG_001 3001
#define MSG_002 3002
#define MSG_003 3003
#define MSG_004 3004
#define MSG_005 3005
#define MSG_006 3006
#define MSG_007 3007
#define MSG_008 3008
#define MSG_009 3009
#define MSG_010 3010
#define MSG_011 3011
#define MSG_012 3012
#define MSG_013 3013
#define MSG_014 3014
#define MSG_015 3015
#define MSG_016 3016
#define MSG_017 3017
#define MSG_018 3018
#define MSG_019 3019
#define MSG_020 3020
#define MSG_021 3021
#define MSG_022 3022
#define MSG_023 3023
#define MSG_024 3024
#define MSG_025 3025
#define MSG_026 3026
#define MSG_027 3027
#define MSG_028 3028
#define MSG_029 3029
#define MSG_030 3030
#define MSG_031 3031
#define MSG_032 3032
#define MSG_033 3033
#define MSG_034 3034
#define MSG_035 3035
#define MSG_036 3036
#define MSG_037 3037
#define MSG_038 3038
#define MSG_039 3039
#define MSG_040 3040
#define MSG_041 3041
#define MSG_042 3042
#define MSG_043 3043
#define MSG_044 3044
#define MSG_045 3045
#define MSG_046 3046
#define MSG_047 3047
#define MSG_048 3048
#define MSG_049 3049
#define MSG_050 3050
#define MSG_051 3051
#define MSG_052 3052
#define MSG_053 3053
#define MSG_054 3054
#define MSG_055 3055
#define MSG_056 3056
#define MSG_057 3057
#define MSG_058 3058
#define MSG_059 3059
#define MSG_060 3060
#define MSG_061 3061
#define MSG_062 3062
#define MSG_063 3063
#define MSG_064 3064
#define MSG_065 3065
#define MSG_066 3066
#define MSG_067 3067
#define MSG_068 3068
#define MSG_069 3069
#define MSG_070 3070
#define MSG_071 3071
#define MSG_072 3072
#define MSG_073 3073
#define MSG_074 3074
#define MSG_075 3075
#define MSG_076 3076
#define MSG_077 3077
#define MSG_078 3078
#define MSG_079 3079
#define MSG_080 3080
#define MSG_081 3081
#define MSG_082 3082
#define MSG_083 3083
#define MSG_084 3084
#define MSG_085 3085
#define MSG_086 3086
#define MSG_087 3087
#define MSG_088 3088
#define MSG_089 3089
#define MSG_090 3090
#define MSG_091 3091
#define MSG_092 3092
#define MSG_093 3093
#define MSG_094 3094
#define MSG_095 3095
#define MSG_096 3096
#define MSG_097 3097
#define MSG_098 3098
#define MSG_099 3099
#define MSG_100 3100
#define MSG_101 3101
#define MSG_102 3102
#define MSG_103 3103
#define MSG_104 3104
#define MSG_105 3105
#define MSG_106 3106
#define MSG_107 3107
#define MSG_108 3108
#define MSG_109 3109
#define MSG_110 3110
#define MSG_111 3111
#define MSG_112 3112
#define MSG_113 3113
#define MSG_114 3114
#define MSG_115 3115
#define MSG_116 3116
#define MSG_117 3117
#define MSG_118 3118
#define MSG_119 3119
#define MSG_120 3120
#define MSG_121 3121
#define MSG_122 3122
#define MSG_123 3123
#define MSG_124 3124
#define MSG_125 3125
#define MSG_126 3126
#define MSG_127 3127
#define MSG_128 3128
#define MSG_129 3129
#define MSG_130 3130
#define MSG_131 3131
#define MSG_132 3132
#define MSG_133 3133
#define MSG_134 3134
#define MSG_135 3135
#define MSG_136 3136
#define MSG_137 3137
#define MSG_138 3138
#define MSG_139 3139
#define MSG_140 3140
#define MSG_141 3141
#define MSG_142 3142
#define MSG_143 3143
#define MSG_144 3144
#define MSG_145 3145
#define MSG_146 3146
#define MSG_147 3147
#define MSG_148 3148
#define MSG_149 3149
#define MSG_150 3150
#define MSG_151 3151
#define MSG_152 3152
#define MSG_153 3153
#define MSG_154 3154
#define MSG_155 3155
#define MSG_156 3156
#define MSG_157 3157
#define MSG_158 3158
#define MSG_159 3159
#define MSG_160 3160
#define MSG_161 3161
#define MSG_162 3162
#define MSG_163 3163
#define MSG_164 3164
#define MSG_165 3165
#define MSG_166 3166
#define MSG_167 3167
#define MSG_168 3168
#define MSG_169 3169
#define MSG_170 3170
#define MSG_171 3171
#define MSG_172 3172
#define MSG_173 3173
#define MSG_174 3174
#define MSG_175 3175
#define MSG_176 3176
#define MSG_177 3177
#define MSG_178 3178
#define MSG_179 3179
#define MSG_180 3180
#define MSG_181 3181
#define MSG_182 3182
#define MSG_183 3183
#define MSG_184 3184
#define MSG_185 3185
#define MSG_186 3186
#define MSG_187 3187
#define MSG_188 3188
#define MSG_189 3189
#define MSG_190 3190
#define MSG_191 3191
#define MSG_192 3192
#define MSG_193 3193
#define MSG_194 3194
#define MSG_195 3195
#define MSG_196 3196
#define MSG_197 3197
#define MSG_198 3198
#define MSG_199 3199
#define MSG_200 3200
#define MSG_201 3201
#define MSG_202 3202
#define MSG_203 3203
#define MSG_204 3204
#define MSG_205 3205
#define MSG_206 3206
#define MSG_207 3207
#define MSG_208 3208
#define MSG_209 3209
#define MSG_210 3210
#define MSG_211 3211
#define MSG_212 3212
#define MSG_213 3213
#define MSG_214 3214
#define MSG_215 3215
#define MSG_216 3216
#define MSG_217 3217
#define MSG_218 3218
#define MSG_219 3219
#define MSG_220 3220
#define MSG_221 3221
#define MSG_222 3222
#define MSG_223 3223
#define MSG_224 3224
#define MSG_225 3225
#define MSG_226 3226
#define MSG_227 3227
#define MSG_228 3228
#define MSG_229 3229
#define MSG_230 3230
#define MSG_231 3231
#define MSG_232 3232
#define MSG_233 3233
#define MSG_234 3234
#define MSG_235 3235
#define MSG_236 3236
#define MSG_237 3237
#define MSG_238 3238
#define MSG_239 3239
#define MSG_240 3240
#define MSG_241 3241
#define MSG_242 3242
#define MSG_243 3243
#define MSG_244 3244
#define MSG_245 3245
#define MSG_246 3246
#define MSG_247 3247
#define MSG_248 3248
#define MSG_249 3249
#define MSG_250 3250
#define MSG_251 3251
#define MSG_252 3252
#define MSG_253 3253
#define MSG_254 3254
#define MSG_255 3255
#define MSG_256 3256
#define MSG_257 3257
#define MSG_258 3258
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 113
#define _APS_NEXT_RESOURCE_VALUE 404
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1071
#define _APS_NEXT_SYMED_VALUE 101
#define _APS_NEXT_SYMED_VALUE 4000
#endif
#endif

View File

@ -40,6 +40,7 @@
#include "resource.h"
#include "rufus.h"
#include "registry.h"
#include "localization.h"
/* Redefinitions for WDK and MinGW */
#ifndef PBM_SETSTATE
@ -88,12 +89,6 @@ struct {
const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT" };
// Number of steps for each FS for FCC_STRUCTURE_PROGRESS
const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10 };
// Don't ask me - just following the MS "standard" here
// We hijack 256 as a "Default" for UDF, since we can't set clustersize there
static const char* ClusterSizeLabel[] = { "Default", "512 bytes", "1024 bytes","2048 bytes","4096 bytes","8192 bytes",
"16 kilobytes", "32 kilobytes", "64 kilobytes", "128 kilobytes", "256 kilobytes", "512 kilobytes",
"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" };
static const char* BiosTypeLabel[BT_MAX] = { "BIOS", "UEFI" };
static const char* PartitionTypeLabel[2] = { "MBR", "GPT" };
static BOOL existing_key = FALSE; // For LGP set/restore
static BOOL size_check = TRUE;
@ -101,6 +96,8 @@ static BOOL log_displayed = FALSE;
static BOOL iso_provided = FALSE;
extern BOOL force_large_fat32, enable_joliet, enable_rockridge;
static int selection_default;
static loc_cmd* selected_locale = NULL;
char ClusterSizeLabel[MAX_CLUSTER_SIZES][64];
char msgbox[1024], msgbox_title[32];
/*
@ -148,6 +145,23 @@ static float previous_end;
#define MB 1048576LL
#define GB 1073741824LL
#define TB 1099511627776LL
/*
* Fill in the cluster size names
*/
static void SetClusterSizeLabels(void)
{
unsigned int i, j, k;
safe_sprintf(ClusterSizeLabel[0], 64, lmprintf(MSG_029));
for (i=512, j=1, k=MSG_026; j<MAX_CLUSTER_SIZES; i<<=1, j++) {
if (i > 8192) {
i /= 1024;
k++;
}
safe_sprintf(ClusterSizeLabel[j], 64, "%d %s", i, lmprintf(k));
}
}
/*
* Set cluster size values according to http://support.microsoft.com/kb/140365
* this call will return FALSE if we can't find a supportable FS for the drive
@ -157,7 +171,7 @@ static BOOL DefineClusterSizes(void)
LONGLONG i;
int fs;
BOOL r = FALSE;
char tmp[64] = "";
char tmp[64] = "", *entry;
default_fs = FS_UNKNOWN;
memset(&SelectedDrive.ClusterSize, 0, sizeof(SelectedDrive.ClusterSize));
@ -278,11 +292,13 @@ out:
safe_strcat(tmp, sizeof(tmp), "Large ");
safe_strcat(tmp, sizeof(tmp), FileSystemLabel[fs]);
if (default_fs == FS_UNKNOWN) {
safe_strcat(tmp, sizeof(tmp), " (Default)");
entry = lmprintf(MSG_030, tmp);
default_fs = fs;
} else {
entry = tmp;
}
IGNORE_RETVAL(ComboBox_SetItemData(hFileSystem,
ComboBox_AddStringU(hFileSystem, tmp), fs));
ComboBox_AddStringU(hFileSystem, entry), fs));
r = TRUE;
}
}
@ -299,7 +315,7 @@ out:
*/
static BOOL SetClusterSizes(int FSType)
{
char szClustSize[64];
char* szClustSize;
int i, k, default_index = 0;
ULONG j;
@ -317,10 +333,11 @@ static BOOL SetClusterSizes(int FSType)
for(i=0,j=0x100,k=0;j<0x10000000;i++,j<<=1) {
if (j & SelectedDrive.ClusterSize[FSType].Allowed) {
safe_sprintf(szClustSize, sizeof(szClustSize), "%s", ClusterSizeLabel[i]);
if (j == SelectedDrive.ClusterSize[FSType].Default) {
safe_strcat(szClustSize, sizeof(szClustSize), " (Default)");
szClustSize = lmprintf(MSG_030, ClusterSizeLabel[i]);
default_index = k;
} else {
szClustSize = ClusterSizeLabel[i];
}
IGNORE_RETVAL(ComboBox_SetItemData(hClusterSize, ComboBox_AddStringU(hClusterSize, szClustSize), j));
k++;
@ -470,15 +487,12 @@ static void SetPartitionSchemeTooltip(void)
bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
if (bt == BT_BIOS) {
CreateTooltip(hPartitionScheme, "Usually the safest choice. If you have an UEFI computer and want to install "
"an OS in EFI mode however, you should select one of the options below", 15000);
CreateTooltip(hPartitionScheme, lmprintf(MSG_150), 15000);
} else {
if (pt == PARTITION_STYLE_MBR) {
CreateTooltip(hPartitionScheme, "Use this if you want to install an OS in EFI mode, but need to access "
"the USB content from Windows XP", 15000);
CreateTooltip(hPartitionScheme, lmprintf(MSG_151), 15000);
} else {
CreateTooltip(hPartitionScheme, "The preferred option to install an OS in EFI mode and when "
"USB access is not required for Windows XP", 15000);
CreateTooltip(hPartitionScheme, lmprintf(MSG_152), 15000);
}
}
}
@ -489,8 +503,6 @@ static void SetPartitionSchemeTooltip(void)
static BOOL PopulateProperties(int ComboIndex)
{
double HumanReadableSize;
char capacity[64];
static char* suffix[] = { "B", "KB", "MB", "GB", "TB", "PB"};
char no_label[] = STR_NO_LABEL;
int i, j, pt, bt;
@ -510,7 +522,7 @@ static BOOL PopulateProperties(int ComboIndex)
EnableBootOptions(TRUE);
HumanReadableSize = (double)SelectedDrive.DiskSize;
for (i=1; i<ARRAYSIZE(suffix); i++) {
for (i=1; i<MAX_SIZE_SUFFIXES; i++) {
HumanReadableSize /= 1024.0;
if (HumanReadableSize < 512.0) {
for (j=0; j<3; j++) {
@ -520,14 +532,14 @@ static BOOL PopulateProperties(int ComboIndex)
continue;
bt = (j==0)?BT_BIOS:BT_UEFI;
pt = (j==2)?PARTITION_STYLE_GPT:PARTITION_STYLE_MBR;
safe_sprintf(capacity, sizeof(capacity), "%s partition scheme for %s%s computer%s",
PartitionTypeLabel[pt], BiosTypeLabel[bt], (j==0)?" or UEFI":"", (j==0)?"s":"");
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme, capacity), (bt<<16)|pt));
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme, ComboBox_AddStringU(hPartitionScheme,
lmprintf(MSG_031+j, PartitionTypeLabel[pt])), (bt<<16)|pt));
}
break;
}
}
if (i >= ARRAYSIZE(suffix))
if (i >= MAX_SIZE_SUFFIXES)
uprintf("Could not populate partition scheme data\n");
if (SelectedDrive.PartitionType == PARTITION_STYLE_GPT) {
j = 2;
@ -548,10 +560,10 @@ static BOOL PopulateProperties(int ComboIndex)
// If we're beneath the tolerance, round proposed label to an integer, if not, show two decimal point
if (fabs(HumanReadableSize / ceil(HumanReadableSize) - 1.0) < PROPOSEDLABEL_TOLERANCE) {
safe_sprintf(SelectedDrive.proposed_label, sizeof(SelectedDrive.proposed_label),
"%0.0f%s", ceil(HumanReadableSize), suffix[i]);
"%0.0f%s", ceil(HumanReadableSize), lmprintf(MSG_020+i));
} else {
safe_sprintf(SelectedDrive.proposed_label, sizeof(SelectedDrive.proposed_label),
"%0.2f%s", HumanReadableSize, suffix[i]);
"%0.2f%s", HumanReadableSize, lmprintf(MSG_020+i));
}
// If no existing label is available and no ISO is selected, propose one according to the size (eg: "256MB", "8GB")
@ -584,9 +596,8 @@ static BOOL GetUSBDevices(DWORD devnum)
LONG maxwidth = 0;
RECT rect;
char drive_letter;
char *label, entry[MAX_PATH], buffer[MAX_PATH];
char *label, *entry, buffer[MAX_PATH];
const char* usbstor_name = "USBSTOR";
const char* generic_friendly_name = "USB Storage Device (Generic)";
GUID _GUID_DEVINTERFACE_DISK = // only known to some...
{ 0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b} };
@ -617,7 +628,7 @@ static BOOL GetUSBDevices(DWORD devnum)
&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) {
uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString());
// We can afford a failure on this call - just replace the name
safe_strcpy(buffer, sizeof(buffer), generic_friendly_name);
safe_strcpy(buffer, sizeof(buffer), lmprintf(MSG_045));
}
uprintf("Found device '%s'\n", buffer);
@ -684,7 +695,7 @@ static BOOL GetUSBDevices(DWORD devnum)
StrArrayAdd(&DriveLabel, label);
// Drive letter ' ' is returned for drives that don't have a volume assigned yet
if (drive_letter == ' ') {
safe_sprintf(entry, sizeof(entry), "%s (Disk %d)", label, device_number.DeviceNumber);
entry = lmprintf(MSG_046, label, device_number.DeviceNumber);
} else {
if (drive_letter == app_dir[0]) {
uprintf("Removing %c: from the list: This is the disk from which " APPLICATION_NAME " is running!\n", drive_letter);
@ -692,7 +703,7 @@ static BOOL GetUSBDevices(DWORD devnum)
safe_free(devint_detail_data);
break;
}
safe_sprintf(entry, sizeof(entry), "%s (%c:)", label, drive_letter);
entry = lmprintf(MSG_047, label, drive_letter);
}
IGNORE_RETVAL(ComboBox_SetItemData(hDeviceList, ComboBox_AddStringU(hDeviceList, entry),
device_number.DeviceNumber + DRIVE_INDEX_MIN));
@ -850,7 +861,7 @@ void UpdateProgress(int op, float percent)
static void EnableControls(BOOL bEnable)
{
EnableWindow(GetDlgItem(hMainDialog, IDC_DEVICE), bEnable);
EnableWindow(GetDlgItem(hMainDialog, IDC_PARTITION_SCHEME), bEnable);
EnableWindow(GetDlgItem(hMainDialog, IDC_PARTITION_TYPE), bEnable);
EnableWindow(GetDlgItem(hMainDialog, IDC_FILESYSTEM), bEnable);
EnableWindow(GetDlgItem(hMainDialog, IDC_CLUSTERSIZE), bEnable);
EnableWindow(GetDlgItem(hMainDialog, IDC_LABEL), bEnable);
@ -864,7 +875,7 @@ static void EnableControls(BOOL bEnable)
EnableWindow(GetDlgItem(hMainDialog, IDC_SET_ICON), bEnable);
EnableWindow(GetDlgItem(hMainDialog, IDC_ADVANCED), bEnable);
EnableWindow(GetDlgItem(hMainDialog, IDC_ENABLE_FIXED_DISKS), bEnable);
SetDlgItemTextA(hMainDialog, IDCANCEL, bEnable?"Close":"Cancel");
SetDlgItemTextU(hMainDialog, IDCANCEL, lmprintf(bEnable?MSG_006:MSG_007));
}
/* Callback for the log window */
@ -878,6 +889,7 @@ BOOL CALLBACK LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
switch (message) {
case WM_INITDIALOG:
apply_localization(IDD_LOG, hDlg);
hLog = GetDlgItem(hDlg, IDC_LOG_EDIT);
// Increase the size of our log textbox to MAX_LOG_SIZE (unsigned word)
PostMessage(hLog, EM_LIMITTEXT, MAX_LOG_SIZE , 0);
@ -907,7 +919,7 @@ BOOL CALLBACK LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
log_size = GetDlgItemTextU(hDlg, IDC_LOG_EDIT, log_buffer, log_size);
if (log_size != 0) {
log_size--; // remove NUL terminator
filepath = FileDialog(TRUE, app_dir, "rufus.log", "log", "Rufus log");
filepath = FileDialog(TRUE, app_dir, "rufus.log", "log", lmprintf(MSG_108));
if (filepath != NULL) {
FileIO(TRUE, filepath, &log_buffer, &log_size);
}
@ -920,6 +932,7 @@ BOOL CALLBACK LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_CLOSE:
ShowWindow(hDlg, SW_HIDE);
reset_localization(IDD_LOG);
log_displayed = FALSE;
return TRUE;
}
@ -960,14 +973,7 @@ static void CALLBACK BlockingTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD
// A write or close operation hasn't made any progress since our last check
user_notified = TRUE;
uprintf("Blocking I/O operation detected\n");
MessageBoxU(hMainDialog,
APPLICATION_NAME " detected that Windows is still flushing its internal buffers\n"
"onto the USB device.\n\n"
"Depending on the speed of your USB device, this operation may\n"
"take a long time to complete, especially for large files.\n\n"
"We recommend that you let Windows finish, to avoid corruption.\n"
"But if you grow tired of waiting, you can just unplug the device...",
RUFUS_BLOCKING_IO_TITLE, MB_OK|MB_ICONINFORMATION);
MessageBoxU(hMainDialog, lmprintf(MSG_080), lmprintf(MSG_048), MB_OK|MB_ICONINFORMATION);
} else {
last_iso_blocking_status = iso_blocking_status;
}
@ -979,6 +985,7 @@ BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_INITDIALOG:
apply_localization(IDD_ISO_EXTRACT, hDlg);
hISOProgressBar = GetDlgItem(hDlg, IDC_PROGRESS);
hISOFileName = GetDlgItem(hDlg, IDC_ISO_FILENAME);
// Use maximum granularity for the progress bar
@ -999,7 +1006,7 @@ BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
switch (LOWORD(wParam)) {
case IDC_ISO_ABORT:
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
PrintStatus(0, FALSE, "Cancelling - Please wait...");
PrintStatus(0, FALSE, lmprintf(MSG_201));
uprintf("Cancelling (from ISO proc.)\n");
EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), FALSE);
if (format_thid != NULL)
@ -1027,10 +1034,10 @@ DWORD WINAPI ISOScanThread(LPVOID param)
if (iso_path == NULL)
goto out;
PrintStatus(0, TRUE, "Scanning ISO image...\n");
PrintStatus(0, TRUE, lmprintf(MSG_202));
if (!ExtractISO(iso_path, "", TRUE)) {
SendMessage(hISOProgressDlg, UM_ISO_EXIT, 0, 0);
PrintStatus(0, TRUE, "Failed to scan ISO image.");
PrintStatus(0, TRUE, lmprintf(MSG_203));
safe_free(iso_path);
goto out;
}
@ -1047,9 +1054,7 @@ DWORD WINAPI ISOScanThread(LPVOID param)
}
}
if ((!iso_report.has_bootmgr) && (!iso_report.has_isolinux) && (!IS_WINPE(iso_report.winpe)) && (!iso_report.has_efi)) {
MessageBoxU(hMainDialog, "This version of " APPLICATION_NAME " only supports bootable ISOs\n"
"based on bootmgr/WinPE, isolinux or EFI.\n"
"This ISO doesn't appear to use either...", "Unsupported ISO", MB_OK|MB_ICONINFORMATION);
MessageBoxU(hMainDialog, lmprintf(MSG_082), lmprintf(MSG_081), MB_OK|MB_ICONINFORMATION);
safe_free(iso_path);
SetMBRProps();
} else if (!iso_report.has_syslinux_v5) { // This check is for Syslinux v4.x or earlier
@ -1063,18 +1068,10 @@ DWORD WINAPI ISOScanThread(LPVOID param)
fclose(fd);
use_own_c32[i] = TRUE;
} else {
PrintStatus(0, FALSE, "Obsolete %s detected", old_c32_name[i]);
safe_sprintf(msgbox, sizeof(msgbox), "This ISO image seems to use an obsolete version of '%s'.\n"
"Boot menus may not may not display properly because of this.\n\n"
"A newer version can be downloaded by " APPLICATION_NAME " to fix this issue:\n"
"- Choose 'Yes' to connect to the internet and download the file\n"
"- Choose 'No' to leave the existing ISO file unmodified\n"
"If you don't know what to do, you should select 'Yes'.\n\n"
"Note: The new file will be downloaded in the current directory and once a "
"'%s' exists there, it will be reused automatically.\n", old_c32_name[i], old_c32_name[i]);
safe_sprintf(msgbox_title, sizeof(msgbox_title), "Replace %s?", old_c32_name[i]);
if (MessageBoxU(hMainDialog, msgbox, msgbox_title, MB_YESNO|MB_ICONWARNING) == IDYES) {
SetWindowTextU(hISOProgressDlg, "Downloading file");
PrintStatus(0, FALSE, lmprintf(MSG_204, old_c32_name[i]));
if (MessageBoxU(hMainDialog, lmprintf(MSG_084, old_c32_name[i], old_c32_name[i]),
lmprintf(MSG_083, old_c32_name[i]), MB_YESNO|MB_ICONWARNING) == IDYES) {
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_085, old_c32_name[i]));
SetWindowTextU(hISOFileName, new_c32_url[i]);
if (DownloadFile(new_c32_url[i], old_c32_name[i], hISOProgressDlg))
use_own_c32[i] = TRUE;
@ -1088,7 +1085,7 @@ DWORD WINAPI ISOScanThread(LPVOID param)
SetFSFromISO();
SetMBRProps();
for (i=(int)safe_strlen(iso_path); (i>0)&&(iso_path[i]!='\\'); i--);
PrintStatus(0, TRUE, "Using ISO: %s\n", &iso_path[i+1]);
PrintStatus(0, TRUE, lmprintf(MSG_205, &iso_path[i+1]));
// Some Linux distros, such as Arch Linux, require the USB drive to have
// a specific label => copy the one we got from the ISO image
if (iso_report.label[0] != 0) {
@ -1105,28 +1102,17 @@ out:
ExitThread(0);
}
void MoveControl(HWND hDlg, int nID, float vertical_shift)
{
RECT rect;
POINT point;
HWND hControl;
hControl = GetDlgItem(hDlg, nID);
GetWindowRect(hControl, &rect);
point.x = rect.left;
point.y = rect.top;
ScreenToClient(hDlg, &point);
GetClientRect(hControl, &rect);
MoveWindow(hControl, point.x, point.y + (int)(fScale*(advanced_mode?vertical_shift:-vertical_shift)),
(rect.right - rect.left), (rect.bottom - rect.top), TRUE);
// Move a control along the Y axis according to the advanced mode setting
void MoveCtrlY(HWND hDlg, int nID, float vertical_shift) {
ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, nID), 0,
(int)(advanced_mode?vertical_shift:-vertical_shift), 0, 0);
}
void SetPassesTooltip(void)
{
char passes_tooltip[32];
safe_strcpy(passes_tooltip, sizeof(passes_tooltip), "Pattern: 0x55, 0xAA, 0xFF, 0x00");
passes_tooltip[13 + ComboBox_GetCurSel(hNBPasses)*6] = 0;
CreateTooltip(hNBPasses, passes_tooltip, -1);
const unsigned char pattern[] = BADBLOCK_PATTERNS;
CreateTooltip(hNBPasses, lmprintf(MSG_153 + ComboBox_GetCurSel(hNBPasses),
pattern[0], pattern[1], pattern[2], pattern[3]), -1);
}
// Toggle "advanced" mode
@ -1147,14 +1133,14 @@ void ToggleAdvanced(void)
point.y + (int)(fScale*(advanced_mode?dialog_shift:-dialog_shift)), TRUE);
// Move the status bar up or down
MoveControl(hMainDialog, IDC_STATUS, dialog_shift);
MoveControl(hMainDialog, IDC_START, dialog_shift);
MoveControl(hMainDialog, IDC_PROGRESS, dialog_shift);
MoveControl(hMainDialog, IDC_ABOUT, dialog_shift);
MoveControl(hMainDialog, IDC_LOG, dialog_shift);
MoveControl(hMainDialog, IDCANCEL, dialog_shift);
MoveCtrlY(hMainDialog, IDC_STATUS, dialog_shift);
MoveCtrlY(hMainDialog, IDC_START, dialog_shift);
MoveCtrlY(hMainDialog, IDC_PROGRESS, dialog_shift);
MoveCtrlY(hMainDialog, IDC_ABOUT, dialog_shift);
MoveCtrlY(hMainDialog, IDC_LOG, dialog_shift);
MoveCtrlY(hMainDialog, IDCANCEL, dialog_shift);
#ifdef RUFUS_TEST
MoveControl(hMainDialogm, IDC_TEST, dialog_shift);
MoveCtrlY(hMainDialog, IDC_TEST, dialog_shift);
#endif
// And do the same for the log dialog while we're at it
@ -1163,9 +1149,9 @@ void ToggleAdvanced(void)
point.y = (rect.bottom - rect.top);
MoveWindow(hLogDlg, rect.left, rect.top, point.x,
point.y + (int)(fScale*(advanced_mode?dialog_shift:-dialog_shift)), TRUE);
MoveControl(hLogDlg, IDC_LOG_CLEAR, dialog_shift);
MoveControl(hLogDlg, IDC_LOG_SAVE, dialog_shift);
MoveControl(hLogDlg, IDCANCEL, dialog_shift);
MoveCtrlY(hLogDlg, IDC_LOG_CLEAR, dialog_shift);
MoveCtrlY(hLogDlg, IDC_LOG_SAVE, dialog_shift);
MoveCtrlY(hLogDlg, IDCANCEL, dialog_shift);
GetWindowRect(hLog, &rect);
point.x = (rect.right - rect.left);
point.y = (rect.bottom - rect.top) + (int)(fScale*(advanced_mode?dialog_shift:-dialog_shift));
@ -1179,7 +1165,7 @@ void ToggleAdvanced(void)
ShowWindow(GetDlgItem(hMainDialog, IDC_EXTRA_PARTITION), toggle);
ShowWindow(GetDlgItem(hMainDialog, IDC_RUFUS_MBR), toggle);
ShowWindow(GetDlgItem(hMainDialog, IDC_DISK_ID), toggle);
ShowWindow(GetDlgItem(hMainDialog, IDC_ADVANCED_GROUP), toggle);
ShowWindow(GetDlgItem(hMainDialog, IDS_ADVANCED_OPTIONS_GRP), toggle);
// Toggle the up/down icon
SendMessage(GetDlgItem(hMainDialog, IDC_ADVANCED), BCM_SETIMAGELIST, 0, (LPARAM)(advanced_mode?&bi_up:&bi_down));
@ -1189,89 +1175,67 @@ static BOOL BootCheck(void)
{
int fs, bt, dt, r;
FILE* fd;
const char* ldlinux_c32 = "ldlinux.c32";
const char* ldlinux_name = "ldlinux.c32";
dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
if (dt == DT_ISO) {
if (iso_path == NULL) {
MessageBoxU(hMainDialog, "Please click on the disc button to select a bootable ISO,\n"
"or uncheck the \"Create a bootable disk...\" checkbox.",
"No ISO image selected", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, lmprintf(MSG_087), lmprintf(MSG_086), MB_OK|MB_ICONERROR);
return FALSE;
}
if ((size_check) && (iso_report.projected_size > (uint64_t)SelectedDrive.DiskSize)) {
MessageBoxU(hMainDialog, "This ISO image is too big "
"for the selected target.", "ISO image too big", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, lmprintf(MSG_089), lmprintf(MSG_088), MB_OK|MB_ICONERROR);
return FALSE;
}
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
if (bt == BT_UEFI) {
if (!IS_EFI(iso_report)) {
MessageBoxU(hMainDialog, "When using UEFI Target Type, only EFI bootable ISO images are supported. "
"Please select an EFI bootable ISO or set the Target Type to BIOS.", "Unsupported ISO", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, lmprintf(MSG_091), lmprintf(MSG_090), MB_OK|MB_ICONERROR);
return FALSE;
} else if (fs > FS_FAT32) {
MessageBoxU(hMainDialog, "When using UEFI Target Type, only FAT/FAT32 is supported. "
"Please select FAT/FAT32 as the File system or set the Target Type to BIOS.", "Unsupported filesystem", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, lmprintf(MSG_093), lmprintf(MSG_092), MB_OK|MB_ICONERROR);
return FALSE;
} else if (iso_report.has_4GB_file) {
// Who the heck decided that using FAT32 for UEFI boot was a great idea?!?
MessageBoxU(hMainDialog, "This ISO image contains a file larger than 4 GB and cannot be used to create an EFI bootable USB.\r\n"
"This is a limitation from UEFI/FAT32, not from " APPLICATION_NAME ".",
"Non UEFI compatible ISO", MB_OK|MB_ICONINFORMATION);
MessageBoxU(hMainDialog, lmprintf(MSG_095), lmprintf(MSG_094), MB_OK|MB_ICONINFORMATION);
return FALSE;
}
} else if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe))) {
if (iso_report.has_isolinux) {
MessageBoxU(hMainDialog, "Only FAT/FAT32 is supported for this type of ISO. "
"Please select FAT/FAT32 as the File system.", "Unsupported filesystem", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK|MB_ICONERROR);
} else {
MessageBoxU(hMainDialog, "Only 'bootmgr' or 'WinPE' based ISO "
"images can currently be used with NTFS.", "Unsupported ISO", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, lmprintf(MSG_097), lmprintf(MSG_090), MB_OK|MB_ICONERROR);
}
return FALSE;
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!iso_report.has_isolinux)) {
MessageBoxU(hMainDialog, "FAT/FAT32 can only be used for isolinux based ISO images "
"or when the Target Type is UEFI.", "Unsupported ISO", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, lmprintf(MSG_098), lmprintf(MSG_090), MB_OK|MB_ICONERROR);
return FALSE;
} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (iso_report.has_4GB_file)) {
MessageBoxU(hMainDialog, "This iso image contains a file larger than 4GB file, which is more than the "
"maximum size allowed for a FAT or FAT32 file system.", "Filesystem limitation", MB_OK|MB_ICONERROR);
MessageBoxU(hMainDialog, lmprintf(MSG_100), lmprintf(MSG_099), MB_OK|MB_ICONERROR);
return FALSE;
}
if ((bt == BT_UEFI) && (iso_report.has_win7_efi) && (!WimExtractCheck())) {
if (MessageBoxU(hMainDialog, "Your platform cannot extract files from WIM archives. WIM extraction "
"is required to create EFI bootable Windows 7 and Windows Vista USB drives. You can fix that "
"by installing a recent version of 7-Zip.\r\nDo you want to visit the 7-zip download page?",
"Missing WIM support", MB_YESNO|MB_ICONERROR) == IDYES)
if (MessageBoxU(hMainDialog, lmprintf(MSG_102), lmprintf(MSG_101), MB_YESNO|MB_ICONERROR) == IDYES)
ShellExecuteA(hMainDialog, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL);
return FALSE;
}
} else if (dt == DT_SYSLINUX_V5) {
_chdirU(app_dir);
fd = fopen(ldlinux_c32, "rb");
fd = fopen(ldlinux_name, "rb");
if (fd != NULL) {
uprintf("Will reuse '%s' for Syslinux v5\n", ldlinux_c32);
uprintf("Will reuse '%s' for Syslinux v5\n", ldlinux_name);
fclose(fd);
} else {
PrintStatus(0, FALSE, "Missing '%s' file", ldlinux_c32);
safe_sprintf(msgbox, sizeof(msgbox), "Syslinux v5.0 or later requires a '%s' file to be installed.\n"
"Because this file is more than 100 KB in size, and always present on Syslinux v5+ ISO images, "
"it is not embedded in " APPLICATION_NAME ".\n\n"
APPLICATION_NAME " can download the missing file for you:\n"
"- Select 'Yes' to connect to the internet and download the file\n"
"- Select 'No' if you want to manually copy this file on the drive later\n\n"
"Note: The file will be downloaded in the current directory and once a "
"'%s' exists there, it will be reused automatically.\n", ldlinux_c32, ldlinux_c32);
safe_sprintf(msgbox_title, sizeof(msgbox_title), "Download %s?", ldlinux_c32);
r = MessageBoxU(hMainDialog, msgbox, msgbox_title, MB_YESNOCANCEL|MB_ICONWARNING);
PrintStatus(0, FALSE, lmprintf(MSG_206, ldlinux_name));
r = MessageBoxU(hMainDialog, lmprintf(MSG_104, ldlinux_name, ldlinux_name),
lmprintf(MSG_103, ldlinux_name), MB_YESNOCANCEL|MB_ICONWARNING);
if (r == IDCANCEL)
return FALSE;
if (r == IDYES) {
SetWindowTextU(hISOProgressDlg, "Downloading file...");
SetWindowTextU(hISOFileName, ldlinux_c32);
DownloadFile(LDLINUX_C32_URL, ldlinux_c32, hISOProgressDlg);
SetWindowTextU(hISOProgressDlg, lmprintf(MSG_085, ldlinux_name));
SetWindowTextU(hISOFileName, LDLINUX_C32_URL);
DownloadFile(LDLINUX_C32_URL, ldlinux_name, hISOProgressDlg);
}
}
}
@ -1295,7 +1259,7 @@ void InitDialog(HWND hDlg)
// Quite a burden to carry around as parameters
hMainDialog = hDlg;
hDeviceList = GetDlgItem(hDlg, IDC_DEVICE);
hPartitionScheme = GetDlgItem(hDlg, IDC_PARTITION_SCHEME);
hPartitionScheme = GetDlgItem(hDlg, IDC_PARTITION_TYPE);
hFileSystem = GetDlgItem(hDlg, IDC_FILESYSTEM);
hClusterSize = GetDlgItem(hDlg, IDC_CLUSTERSIZE);
hLabel = GetDlgItem(hDlg, IDC_LABEL);
@ -1344,6 +1308,11 @@ void InitDialog(HWND hDlg)
}
uprintf("Windows version: %s %d-bit\n", PrintWindowsVersion(nWindowsVersion), is_x64?64:32);
// Detect the LCID
uprintf("LCID: 0x%04X\n", GetUserDefaultLCID());
SetClusterSizeLabels();
// Prefer FreeDOS to MS-DOS
selection_default = DT_FREEDOS;
// Create the status line and initialize the taskbar icon for progress overlay
@ -1355,21 +1324,19 @@ void InitDialog(HWND hDlg)
SendMessage(hProgress, PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000);
// Fill up the passes
for (i=0; i<4; i++) {
safe_sprintf(tmp, sizeof(tmp), "%d Pass%s", i+1, (i==0)?"":"es");
IGNORE_RETVAL(ComboBox_AddStringU(hNBPasses, tmp));
IGNORE_RETVAL(ComboBox_AddStringU(hNBPasses, lmprintf((i==0)?MSG_034:MSG_035, i+1)));
}
IGNORE_RETVAL(ComboBox_SetCurSel(hNBPasses, 1));
SetPassesTooltip();
// Fill up the DOS type dropdown
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), DT_WINME));
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), DT_FREEDOS));
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "ISO Image"), DT_ISO));
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, lmprintf(MSG_036)), DT_ISO));
IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, selection_default));
// Fill up the MBR masqueraded disk IDs ("8 disks should be enough for anybody")
IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, "0x80 (default)"), 0x80));
IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, lmprintf(MSG_030, "0x80")), 0x80));
for (i=1; i<=7; i++) {
sprintf(tmp, "0x%02x (%d%s disk)", 0x80+i, i+1, (i==1)?"nd":((i==2)?"rd":"th"));
IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, tmp), 0x80+i));
IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, lmprintf(MSG_109, 0x80+i, i+1)), 0x80+i));
}
IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0));
@ -1413,26 +1380,23 @@ void InitDialog(HWND hDlg)
SendMessage(GetDlgItem(hDlg, IDC_ADVANCED), BCM_SETIMAGELIST, 0, (LPARAM)&bi_down);
// Set the various tooltips
CreateTooltip(hFileSystem, "Sets the target filesystem", -1);
CreateTooltip(hClusterSize, "Minimum size that each data block occupies", -1);
CreateTooltip(hLabel, "Use this field to set the drive label\nInternational characters are accepted", -1);
CreateTooltip(GetDlgItem(hDlg, IDC_ADVANCED), "Toggle advanced options", -1);
CreateTooltip(GetDlgItem(hDlg, IDC_BADBLOCKS), "Test the device for bad blocks using a byte pattern", -1);
CreateTooltip(GetDlgItem(hDlg, IDC_QUICKFORMAT), "Unchek this box to use the \"slow\" format method", -1);
CreateTooltip(hBoot, "Check this box to make the USB drive bootable", -1);
CreateTooltip(hBootType, "Boot method", -1);
CreateTooltip(hSelectISO, "Click to select an ISO...", -1);
CreateTooltip(GetDlgItem(hDlg, IDC_SET_ICON), "Check this box to allow the display of international labels "
"and set a device icon (creates an autorun.inf)", 10000);
CreateTooltip(GetDlgItem(hDlg, IDC_RUFUS_MBR), "Install an MBR that allows boot selection and can masquerade the BIOS USB drive ID", 10000);
CreateTooltip(hDiskID, "Try to masquerade first bootable USB drive (usually 0x80) as a different disk.\n"
"This should only be necessary for XP installation" , 10000);
CreateTooltip(GetDlgItem(hDlg, IDC_EXTRA_PARTITION), "Create an extra hidden partition and try to align partitions boundaries.\n"
"This can improve boot detection for older BIOSes", -1);
CreateTooltip(GetDlgItem(hDlg, IDC_ENABLE_FIXED_DISKS), "Enable detection for disks not normally detected by " APPLICATION_NAME ". "
"USE AT YOUR OWN RISKS!!!", -1);
CreateTooltip(GetDlgItem(hDlg, IDC_START), "Start the formatting operation.\nThis will DESTROY any data on the target!", -1);
CreateTooltip(GetDlgItem(hDlg, IDC_ABOUT), "Licensing information and credits", -1);
CreateTooltip(hFileSystem, lmprintf(MSG_157), -1);
CreateTooltip(hClusterSize, lmprintf(MSG_158), -1);
CreateTooltip(hLabel, lmprintf(MSG_159), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_ADVANCED), lmprintf(MSG_160), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_BADBLOCKS), lmprintf(MSG_161), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_QUICKFORMAT), lmprintf(MSG_162), -1);
CreateTooltip(hBoot, lmprintf(MSG_163), -1);
CreateTooltip(hBootType, lmprintf(MSG_164), -1);
CreateTooltip(hSelectISO, lmprintf(MSG_165), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_SET_ICON), lmprintf(MSG_166), 10000);
CreateTooltip(GetDlgItem(hDlg, IDC_RUFUS_MBR), lmprintf(MSG_167), 10000);
CreateTooltip(hDiskID, lmprintf(MSG_168), 10000);
CreateTooltip(GetDlgItem(hDlg, IDC_EXTRA_PARTITION), lmprintf(MSG_169), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_ENABLE_FIXED_DISKS), lmprintf(MSG_170), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_START), lmprintf(MSG_171), -1);
CreateTooltip(GetDlgItem(hDlg, IDC_ABOUT), lmprintf(MSG_172), -1);
// TODO: add new tooltips
ToggleAdvanced(); // We start in advanced mode => go to basic mode
@ -1445,9 +1409,10 @@ void InitDialog(HWND hDlg)
static void PrintStatus2000(const char* str, BOOL val)
{
PrintStatus(2000, FALSE, "%s %s.", str, (val)?"enabled":"disabled");
PrintStatus(2000, FALSE, (lmprintf((val)?MSG_250:MSG_251, str)));
}
/*
* Main dialog callback
*/
@ -1456,9 +1421,9 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
DRAWITEMSTRUCT* pDI;
POINT Point;
RECT DialogRect, DesktopRect;
int nDeviceIndex, fs, bt, i, nWidth, nHeight;
int nDeviceIndex, fs, bt, i, nWidth, nHeight, nb_devices;
static DWORD DeviceNum = 0, LastRefresh = 0;
char tmp[128], str[MAX_PATH];
char tmp[128];
static UINT uBootChecked = BST_CHECKED, uQFChecked;
static BOOL first_log_display = TRUE, user_changed_label = FALSE;
@ -1497,9 +1462,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
break;
case WM_INITDIALOG:
apply_localization(IDD_DIALOG, hDlg);
SetUpdateCheck();
// Create the log window (hidden)
hLogDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_LOG), hDlg, (DLGPROC)LogProc);
hLogDlg = CreateDialogW(hMainInstance, MAKEINTRESOURCEW(IDD_LOG), hDlg, (DLGPROC)LogProc);
InitDialog(hDlg);
GetUSBDevices(0);
CheckForUpdates(FALSE);
@ -1533,13 +1499,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), FALSE);
EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
if (format_thid != NULL) {
if (MessageBoxU(hMainDialog, "Cancelling may leave the device in an UNUSABLE state.\r\n"
"If you are sure you want to cancel, click YES. Otherwise, click NO.",
RUFUS_CANCELBOX_TITLE, MB_YESNO|MB_ICONWARNING) == IDYES) {
if (MessageBoxU(hMainDialog, lmprintf(MSG_105), lmprintf(MSG_049),
MB_YESNO|MB_ICONWARNING) == IDYES) {
// Operation may have completed in the meantime
if (format_thid != NULL) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
PrintStatus(0, FALSE, "Cancelling - Please wait...");
PrintStatus(0, FALSE, lmprintf(MSG_201));
uprintf("Cancelling (from main app)\n");
// Start a timer to detect blocking operations during ISO file extraction
if (iso_blocking_status >= 0) {
@ -1606,8 +1571,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
case IDC_DEVICE:
if (HIWORD(wParam) != CBN_SELCHANGE)
break;
PrintStatus(0, TRUE, "%d device%s found.", ComboBox_GetCount(hDeviceList),
(ComboBox_GetCount(hDeviceList)!=1)?"s":"");
nb_devices = ComboBox_GetCount(hDeviceList);
PrintStatus(0, TRUE, lmprintf((nb_devices==1)?MSG_208:MSG_209, nb_devices));
PopulateProperties(ComboBox_GetCurSel(hDeviceList));
SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_FILESYSTEM,
ComboBox_GetCurSel(hFileSystem));
@ -1617,7 +1582,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
break;
SetPassesTooltip();
break;
case IDC_PARTITION_SCHEME:
case IDC_PARTITION_TYPE:
if (HIWORD(wParam) != CBN_SELCHANGE)
break;
SetPartitionSchemeTooltip();
@ -1673,7 +1638,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), DT_WINME));
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), DT_FREEDOS));
}
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "ISO Image"), DT_ISO));
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, lmprintf(MSG_036)), DT_ISO));
// If needed (advanced mode) also append a Syslinux option
if ( (bt == BT_BIOS) && (((fs == FS_FAT16) || (fs == FS_FAT32)) && (advanced_mode)) ) {
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "Syslinux 4"), DT_SYSLINUX_V4));
@ -1729,9 +1694,9 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
iso_provided = FALSE; // One off thing...
} else {
safe_free(iso_path);
iso_path = FileDialog(FALSE, NULL, "*.iso", "iso", "ISO Image");
iso_path = FileDialog(FALSE, NULL, "*.iso", "iso", lmprintf(MSG_036));
if (iso_path == NULL) {
CreateTooltip(hSelectISO, "Click to select...", -1);
CreateTooltip(hSelectISO, lmprintf(MSG_173), -1);
break;
}
}
@ -1750,7 +1715,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
case IDC_ENABLE_FIXED_DISKS:
if ((HIWORD(wParam)) == BN_CLICKED) {
enable_fixed_disks = !enable_fixed_disks;
PrintStatus2000("Fixed disks detection", enable_fixed_disks);
PrintStatus2000(lmprintf(MSG_253), enable_fixed_disks);
GetUSBDevices(0);
}
break;
@ -1773,9 +1738,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
break;
}
GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp));
_snprintf(str, ARRAYSIZE(str), "WARNING: ALL DATA ON DEVICE '%s'\r\nWILL BE DESTROYED.\r\n"
"To continue with this operation, click OK. To quit click CANCEL.", tmp);
if (MessageBoxU(hMainDialog, str, APPLICATION_NAME, MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL) {
if (MessageBoxU(hMainDialog, lmprintf(MSG_003, tmp),
APPLICATION_NAME, MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL) {
format_op_in_progress = FALSE;
break;
}
@ -1818,7 +1782,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
// You'd think that Windows would let you instantiate a modeless dialog wherever
// but you'd be wrong. It must be done in the main callback, hence the custom message.
if (!IsWindow(hISOProgressDlg)) {
hISOProgressDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_ISO_EXTRACT),
hISOProgressDlg = CreateDialogW(hMainInstance, MAKEINTRESOURCEW(IDD_ISO_EXTRACT),
hDlg, (DLGPROC)ISOProc);
// The window is not visible by default but takes focus => restore it
SetFocus(hDlg);
@ -1830,8 +1794,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
// Stop the timer
KillTimer(hMainDialog, TID_APP_TIMER);
// Close the cancel MessageBox and Blocking notification if active
SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), RUFUS_CANCELBOX_TITLE), WM_COMMAND, IDNO, 0);
SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), RUFUS_BLOCKING_IO_TITLE), WM_COMMAND, IDYES, 0);
SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), lmprintf(MSG_049)), WM_COMMAND, IDNO, 0);
SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), lmprintf(MSG_049)), WM_COMMAND, IDYES, 0);
EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), TRUE);
EnableWindow(GetDlgItem(hMainDialog, IDCANCEL), TRUE);
EnableControls(TRUE);
@ -1843,17 +1807,17 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
SendMessage(hProgress, PBM_SETPOS, (MAX_PROGRESS+1), 0);
SendMessage(hProgress, PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000);
SetTaskbarProgressState(TASKBAR_NOPROGRESS);
PrintStatus(0, FALSE, "DONE");
PrintStatus(0, FALSE, lmprintf(MSG_210));
} else if (SCODE_CODE(FormatStatus) == ERROR_CANCELLED) {
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_PAUSED, 0);
SetTaskbarProgressState(TASKBAR_PAUSED);
PrintStatus(0, FALSE, "Cancelled");
Notification(MSG_INFO, NULL, "Cancelled", "Operation cancelled by the user.");
PrintStatus(0, FALSE, lmprintf(MSG_211));
Notification(MSG_INFO, NULL, lmprintf(MSG_211), lmprintf(MSG_041));
} else {
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_ERROR, 0);
SetTaskbarProgressState(TASKBAR_ERROR);
PrintStatus(0, FALSE, "FAILED");
Notification(MSG_ERROR, NULL, "Error", "Error: %s", StrError(FormatStatus));
PrintStatus(0, FALSE, lmprintf(MSG_212));
Notification(MSG_ERROR, NULL, lmprintf(MSG_042), lmprintf(MSG_043), StrError(FormatStatus));
}
FormatStatus = 0;
format_op_in_progress = FALSE;
@ -1912,10 +1876,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
const char* old_wait_option = "/W";
int i, opt, option_index = 0, argc = 0, si = 0;
BOOL attached_console = FALSE;
BYTE* loc_data;
DWORD loc_size, Size;
char tmp_path[MAX_PATH], loc_file[MAX_PATH] = "", *locale_name = NULL;
char** argv = NULL;
wchar_t **wenv, **wargv;
PF_DECL(__wgetmainargs);
HANDLE mutex = NULL;
HANDLE mutex = NULL, hFile = NULL;
HWND hDlg = NULL;
MSG msg;
int wait_for_mutex = 0;
@ -1938,7 +1905,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
printf("\n");
}
// We have to process the arguments before we acquire the lock
// We have to process the arguments before we acquire the lock and process the locale
PF_INIT(__wgetmainargs, msvcrt);
if (pf__wgetmainargs != NULL) {
pf__wgetmainargs(&argc, &wargv, &wenv, 1, &si);
@ -1950,7 +1917,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
wait_for_mutex = 150; // Try to acquire the mutex for 15 seconds
}
while ((opt = getopt_long(argc, argv, "?fhi:w:", long_options, &option_index)) != EOF)
while ((opt = getopt_long(argc, argv, "?fhi:w:l:", long_options, &option_index)) != EOF)
switch (opt) {
case 'f':
enable_fixed_disks = TRUE;
@ -1963,6 +1930,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
printf("Could not find ISO image '%s'\n", optarg);
}
break;
case 'l':
// TODO: accept a locale code such as 0x409
locale_name = optarg;
break;
case 'w':
wait_for_mutex = atoi(optarg);
break;
@ -1976,6 +1947,44 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
uprintf("unable to access UTF-16 args");
}
// Retrieve the current application directory
GetCurrentDirectoryU(MAX_PATH, app_dir);
// Init localization
init_localization();
// Seek for a loc file in the current directory
if (GetFileAttributesU("rufus.loc") == INVALID_FILE_ATTRIBUTES) {
uprintf("loc file not found in current directory - embedded one will be used");
loc_data = (BYTE*)GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_LC_RUFUS_LOC), _RT_RCDATA, "rufus.loc", &loc_size, FALSE);
GetTempPathU(sizeof(tmp_path), tmp_path);
GetTempFileNameU(tmp_path, APPLICATION_NAME, 0, loc_file);
hFile = CreateFileU(loc_file, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, 0, 0);
if ((hFile == INVALID_HANDLE_VALUE)|| (!WriteFile(hFile, loc_data, loc_size, &Size, 0)) || (loc_size != Size)) {
safe_closehandle(hFile);
uprintf("localization: unable to extract '%s': %s.\n", loc_file, WindowsErrorString());
} else {
safe_closehandle(hFile);
uprintf("localization: extracted data to '%s'\n", loc_file);
}
} else {
safe_sprintf(loc_file, sizeof(loc_file), "%s\\rufus.loc", app_dir);
uprintf("using external loc file '%s'", loc_file);
}
if ( (!get_supported_locales(loc_file))
|| ((selected_locale = ((locale_name == NULL)?get_locale_from_lcid(GetUserDefaultLCID()):get_locale_from_name(locale_name))) == NULL) ) {
uprintf("FATAL: Could not access locale!\n");
MessageBoxU(NULL, "The locale data is missing. This application will now exit.",
"Fatal error", MB_ICONSTOP);
goto out;
}
uprintf("localization: using locale '%s'\n", selected_locale->txt[0]);
get_loc_data_file(loc_file, (long)selected_locale->num[0], (long)selected_locale->num[1], selected_locale->line_nr);
// Prevent 2 applications from running at the same time, unless "/W" is passed as an option
// in which case we wait for the mutex to be relinquished
if ((safe_strlen(lpCmdLine)==2) && (lpCmdLine[0] == '/') && (lpCmdLine[1] == 'W'))
@ -1987,9 +1996,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
mutex = CreateMutexA(NULL, TRUE, "Global/" APPLICATION_NAME);
}
if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) {
MessageBoxU(NULL, "Another " APPLICATION_NAME " application is running.\n"
"Please close the first application before running another one.",
"Other instance detected", MB_ICONSTOP);
MessageBoxU(NULL, lmprintf(MSG_002), lmprintf(MSG_001), MB_ICONSTOP);
goto out;
}
@ -2004,9 +2011,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
uprintf("Could not load RichEdit library - some dialogs may not display: %s\n", WindowsErrorString());
}
// Retrieve the current application directory
GetCurrentDirectoryU(MAX_PATH, app_dir);
// Set the Windows version
nWindowsVersion = DetectWindowsVersion();
@ -2015,7 +2019,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
SetLGP(FALSE, &existing_key, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0x9e);
// Create the main Window
if ( (hDlg = CreateDialogA(hInstance, MAKEINTRESOURCEA(IDD_DIALOG), NULL, MainCallback)) == NULL ) {
hDlg = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG), NULL, MainCallback);
if (hDlg == NULL) {
MessageBoxU(NULL, "Could not create Window", "DialogBox failure", MB_ICONSTOP);
goto out;
}
@ -2031,7 +2036,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// the target USB drive. If this is enabled, the size check is disabled.
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'S')) {
size_check = !size_check;
PrintStatus2000("Size checks", size_check);
PrintStatus2000(lmprintf(MSG_252), size_check);
GetUSBDevices(0);
continue;
}
@ -2041,20 +2046,20 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// drive instead of an USB key. If this is enabled, Rufus will allow fixed disk formatting.
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'F')) {
enable_fixed_disks = !enable_fixed_disks;
PrintStatus2000("Fixed disks detection", enable_fixed_disks);
PrintStatus2000(lmprintf(MSG_253), enable_fixed_disks);
GetUSBDevices(0);
continue;
}
// Alt-L => Force Large FAT32 format to be used on < 32 GB drives
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'L')) {
force_large_fat32 = !force_large_fat32;
PrintStatus2000("Force large FAT32 usage", force_large_fat32);
PrintStatus2000(lmprintf(MSG_254), force_large_fat32);
continue;
}
// Alt-D => Delete the NoDriveTypeAutorun key on exit (useful if the app crashed)
// This key is used to disable Windows popup messages when an USB drive is plugged in.
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'D')) {
PrintStatus(2000, FALSE, "NoDriveTypeAutorun will be deleted on exit.");
PrintStatus(2000, FALSE, lmprintf(MSG_255));
existing_key = FALSE;
continue;
}
@ -2064,13 +2069,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// a file name). This option allows users to ignore Joliet when using such images.
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'J')) {
enable_joliet = !enable_joliet;
PrintStatus2000("Joliet support", enable_joliet);
PrintStatus2000(lmprintf(MSG_257), enable_joliet);
continue;
}
// Alt K => Toggle Rock Ridge support for ISO9660 image
// Alt K => Toggle Rock Ridge support for ISO9660 images
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'K')) {
enable_rockridge = !enable_rockridge;
PrintStatus2000("Rock Ridge support", enable_rockridge);
PrintStatus2000(lmprintf(MSG_258), enable_rockridge);
continue;
}
// Alt L => Toggle fake drive detection during bad blocks check
@ -2080,13 +2085,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// it back during the bad block check.
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'L')) {
detect_fakes = !detect_fakes;
PrintStatus2000("Fake drive detection", detect_fakes);
PrintStatus2000(lmprintf(MSG_256), detect_fakes);
continue;
}
// Alt-R => Remove all the registry keys created by Rufus
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'R')) {
PrintStatus(2000, FALSE, "Application registry key %s deleted.",
DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME "\\" APPLICATION_NAME)?"successfully":"could not be");
PrintStatus(2000, FALSE, lmprintf(DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME "\\" APPLICATION_NAME)?MSG_248:MSG_249));
// Also try to delete the upper key (company name) if it's empty (don't care about the result)
DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME);
continue;
@ -2097,7 +2101,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
}
out:
if (loc_file[0] != 0)
DeleteFileU(loc_file);
DestroyAllTooltips();
exit_localization();
safe_free(iso_path);
safe_free(update.download_url);
safe_free(update.release_notes);

View File

@ -17,6 +17,7 @@
*/
#include <windows.h>
#include <winioctl.h> // for DISK_GEOMETRY
#include <malloc.h>
#include <stdint.h>
#if defined(_MSC_VER)
@ -29,19 +30,19 @@
/* Program options */
#define RUFUS_DEBUG // print debug info to Debug facility
/* Features not ready for prime time and that may *DESTROY* your data - USE AT YOUR OWN RISKS! */
//#define RUFUS_TEST
// #define RUFUS_TEST
#define APPLICATION_NAME "Rufus"
#define COMPANY_NAME "Akeo Consulting"
#define STR_NO_LABEL "NO_LABEL"
#define RUFUS_CANCELBOX_TITLE APPLICATION_NAME " - Cancellation"
#define RUFUS_BLOCKING_IO_TITLE APPLICATION_NAME " - Flushing buffers"
#define DRIVE_ACCESS_TIMEOUT 15000 // How long we should retry drive access (in ms)
#define DRIVE_ACCESS_RETRIES 60 // How many times we should retry
#define DRIVE_INDEX_MIN 0x00000080
#define DRIVE_INDEX_MAX 0x000000C0
#define MAX_DRIVES (DRIVE_INDEX_MAX - DRIVE_INDEX_MIN)
#define MAX_TOOLTIPS 32
#define MAX_TOOLTIPS 128
#define MAX_SIZE_SUFFIXES 6 // bytes, KB, MB, GB, TB, PB
#define MAX_CLUSTER_SIZES 18
#define MAX_PROGRESS (0xFFFF-1) // leave room for 1 more for insta-progress workaround
#define MAX_LOG_SIZE 0x7FFFFFFE
#define MAX_GUID_STRING_LENGTH 40
@ -50,6 +51,7 @@
#define MBR_UEFI_MARKER 0x49464555 // 'U', 'E', 'F', 'I', as a 32 bit little endian longword
#define PROPOSEDLABEL_TOLERANCE 0.10
#define FS_DEFAULT FS_FAT32
#define BADBLOCK_PATTERNS {0xaa, 0x55, 0xff, 0x00}
#define LARGE_FAT32_SIZE (32*1073741824LL) // Size at which we need to use fat32format
#define MAX_FAT32_SIZE 2.0f // Threshold above which we disable FAT32 formatting (in TB)
#define WHITE RGB(255,255,255)
@ -283,12 +285,13 @@ extern enum WindowsVersion DetectWindowsVersion(void);
extern const char* PrintWindowsVersion(enum WindowsVersion version);
extern const char *WindowsErrorString(void);
extern void DumpBufferHex(void *buf, size_t size);
extern void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...);
extern void PrintStatus(unsigned int duration, BOOL debug, const char* message);
extern void UpdateProgress(int op, float percent);
extern const char* StrError(DWORD error_code);
extern char* GuidToString(const GUID* guid);
extern char* SizeToHumanReadable(LARGE_INTEGER size);
extern void CenterDialog(HWND hDlg);
extern void ResizeMoveCtrl(HWND hDlg, HWND hCtrl, int dx, int dy, int dw, int dh);
extern void CreateStatusBar(void);
extern void SetTitleBarIcon(HWND hDlg);
extern BOOL CreateTaskbarList(void);
@ -342,12 +345,20 @@ extern void parse_update(char* buf, size_t len);
extern BOOL WimExtractCheck(void);
extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst);
__inline static BOOL UnlockDrive(HANDLE hDrive)
static __inline BOOL UnlockDrive(HANDLE hDrive)
{
DWORD size;
return DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL);
}
static __inline void *_reallocf(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
if (!ret)
free(ptr);
return ret;
}
/* Basic String Array */
typedef struct {
char** Table;

View File

@ -30,48 +30,48 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 329
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Rufus v1.4.0.280"
CAPTION "Rufus v1.4.0.281"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,291,50,14
PUSHBUTTON "Close",IDCANCEL,148,291,50,14
COMBOBOX IDC_DEVICE,8,17,190,33,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Device",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,9,6,22,8
COMBOBOX IDC_FILESYSTEM,8,75,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "File system",IDC_STATIC,9,64,51,10
COMBOBOX IDC_PARTITION_SCHEME,8,46,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Partition scheme and target system type",IDC_STATIC,9,35,176,8
COMBOBOX IDC_CLUSTERSIZE,8,104,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Cluster size",IDC_STATIC,9,93,105,10
PUSHBUTTON "About...",IDC_ABOUT,8,291,50,14
GROUPBOX "Format Options ",IDC_STATIC,7,149,192,66
PUSHBUTTON "Log",IDC_LOG,62,291,18,14
PUSHBUTTON "T",IDC_TEST,80,291,12,14,NOT WS_VISIBLE
COMBOBOX IDC_DEVICE,8,17,190,33,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Device",IDS_DEVICE_TXT,9,6,186,8
COMBOBOX IDC_FILESYSTEM,8,75,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "File system",IDS_FILESYSTEM_TXT,9,64,186,10
COMBOBOX IDC_PARTITION_TYPE,8,46,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Partition scheme and target system type",IDS_PARTITION_TYPE_TXT,9,35,186,8
COMBOBOX IDC_CLUSTERSIZE,8,104,190,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Cluster size",IDS_CLUSTERSIZE_TXT,9,93,186,10
GROUPBOX "Format Options ",IDS_FORMAT_OPTIONS_GRP,7,149,192,66
LTEXT "New volume label",IDS_LABEL_TXT,9,121,186,10
EDITTEXT IDC_LABEL,7,131,190,13,ES_AUTOHSCROLL
CONTROL "Check device for bad blocks:",IDC_BADBLOCKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,161,101,10
CONTROL "Quick format",IDC_QUICKFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,173,55,10
CONTROL "Quick format",IDC_QUICKFORMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,173,181,10
CONTROL "Create a bootable disk using:",IDC_BOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,185,104,10
CONTROL "Create extended label and icon files",IDC_SET_ICON,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,198,131,10
LTEXT "New volume label",IDC_STATIC,9,121,105,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,198,181,10
CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | WS_BORDER,8,272,189,9
COMBOBOX IDC_NBPASSES,119,159,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_BOOTTYPE,119,183,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "...",IDC_SELECT_ISO,171,182,22,14,BS_ICON
PUSHBUTTON "T",IDC_TEST,80,291,12,14,NOT WS_VISIBLE
CONTROL "Use Rufus MBR with BIOS ID:",IDC_RUFUS_MBR,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,13,248,106,10
CONTROL "Use Rufus MBR with BIOS ID:",IDC_RUFUS_MBR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,248,106,10
PUSHBUTTON "",IDC_ADVANCED,63,148,14,10,BS_TOP | BS_FLAT
GROUPBOX "Advanced Options",IDC_ADVANCED_GROUP,7,210,192,54,NOT WS_VISIBLE
COMBOBOX IDC_DISK_ID,119,246,73,30,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Advanced Options",IDS_ADVANCED_OPTIONS_GRP,7,210,192,54
COMBOBOX IDC_DISK_ID,119,246,73,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Add fixes for old BIOSes (extra partition, align, etc.)",IDC_EXTRA_PARTITION,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,235,184,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,235,181,10
CONTROL "List fixed (non-flash) or unpartitioned USB disks",IDC_ENABLE_FIXED_DISKS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,222,185,10
PUSHBUTTON "Log",IDC_LOG,62,291,18,14
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,222,181,10
END
IDD_ABOUTBOX DIALOGEX 0, 0, 287, 201
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Rufus"
FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
ICON IDI_ICON,IDC_ABOUT_ICON,11,8,20,20
DEFPUSHBUTTON "OK",IDOK,231,181,50,14,WS_GROUP
@ -128,36 +128,35 @@ END
IDD_UPDATE_POLICY DIALOGEX 0, 0, 287, 198
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Update policy and settings"
FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
ICON IDI_ICON,IDC_ABOUT_ICON,11,8,21,20
ICON IDI_ICON,IDC_ABOUT_ICON,11,8,20,20
DEFPUSHBUTTON "Close",IDCANCEL,221,172,50,14,WS_GROUP
CONTROL "",IDC_POLICY,"RichEdit20W",WS_VSCROLL | 0x804,46,8,235,130,WS_EX_STATICEDGE
COMBOBOX IDC_UPDATE_FREQUENCY,133,155,66,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Check for updates:",IDC_STATIC,52,157,72,11
LTEXT "Include beta versions:",IDC_STATIC,52,173,93,11
LTEXT "Check for updates:",IDS_UPDATE_FREQUENCY_TXT,52,157,80,11
LTEXT "Include beta versions:",IDS_INCLUDE_BETAS_TXT,52,173,80,11
COMBOBOX IDC_INCLUDE_BETAS,133,171,36,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Settings",IDC_STATIC,45,145,161,46
GROUPBOX "Settings",IDS_UPDATE_SETTINGS_GRP,45,145,161,46
PUSHBUTTON "Check Now",IDC_CHECK_NOW,221,154,50,14
GROUPBOX "",IDC_STATIC,210,145,71,46
GROUPBOX "",IDS_CHECK_NOW_GRP,210,145,71,46
END
IDD_NEW_VERSION DIALOGEX 0, 0, 384, 268
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Check For Updates - Rufus"
FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
PUSHBUTTON "Close",IDCANCEL,167,244,50,14,WS_GROUP
CONTROL "",IDC_RELEASE_NOTES,"RichEdit20W",WS_VSCROLL | 0x804,15,77,352,88,WS_EX_STATICEDGE
CONTROL "",IDC_RELEASE_NOTES,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL,15,77,352,88,WS_EX_STATICEDGE
DEFPUSHBUTTON "Download",IDC_DOWNLOAD,293,211,74,14,WS_GROUP
CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,15,212,270,11
GROUPBOX "Release Notes",IDC_STATIC,8,63,367,111
LTEXT "A newer version is available. Please download the latest version!",IDC_STATIC,10,32,229,8
GROUPBOX "Release Notes",IDS_NEW_VERSION_NOTES_GRP,8,63,367,111
LTEXT "A newer version is available. Please download the latest version!",IDS_NEW_VERSION_AVAIL_TXT,10,32,229,8
LTEXT "[...]",IDC_YOUR_VERSION,10,8,124,8
LTEXT "[...]",IDC_LATEST_VERSION,10,19,129,8
CONTROL "<a href=""http://rufus.akeo.ie"">Click here to go to the website</a>",IDC_WEBSITE,
"SysLink",WS_TABSTOP,143,49,96,9
GROUPBOX "Download",IDC_STATIC,8,177,367,58
LTEXT " Click here to go to the website",IDC_WEBSITE,138,49,108,9,SS_NOTIFY
GROUPBOX "Download",IDS_NEW_VERSION_DOWNLOAD_GRP,8,177,367,58
EDITTEXT IDC_DOWNLOAD_URL,15,191,351,13,ES_AUTOHSCROLL | ES_READONLY
END
@ -185,6 +184,7 @@ END
3 TEXTINCLUDE
BEGIN
"\r\n"
"IDR_LC_RUFUS_LOC RCDATA ""../res/localization/rufus.loc""\r\n"
"IDR_SL_LDLINUX_V4_BSS RCDATA ""../res/syslinux/ldlinux_v4.bss""\r\n"
"IDR_SL_LDLINUX_V4_SYS RCDATA ""../res/syslinux/ldlinux_v4.sys""\r\n"
"IDR_SL_LDLINUX_V5_BSS RCDATA ""../res/syslinux/ldlinux_v5.bss""\r\n"
@ -278,8 +278,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,0,280
PRODUCTVERSION 1,4,0,280
FILEVERSION 1,4,0,281
PRODUCTVERSION 1,4,0,281
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -296,13 +296,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.4.0.280"
VALUE "FileVersion", "1.4.0.281"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2013 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.4.0.280"
VALUE "ProductVersion", "1.4.0.281"
END
END
BLOCK "VarFileInfo"
@ -333,6 +333,7 @@ IDI_DOWN ICON "../res/down.ico"
// Generated from the TEXTINCLUDE 3 resource.
//
IDR_LC_RUFUS_LOC RCDATA "../res/localization/rufus.loc"
IDR_SL_LDLINUX_V4_BSS RCDATA "../res/syslinux/ldlinux_v4.bss"
IDR_SL_LDLINUX_V4_SYS RCDATA "../res/syslinux/ldlinux_v4.sys"
IDR_SL_LDLINUX_V5_BSS RCDATA "../res/syslinux/ldlinux_v5.bss"

View File

@ -26,6 +26,8 @@
#include "msapi_utf8.h"
#include "rufus.h"
#include "resource.h"
#include "localization.h"
// Must be in the same order as enum WindowsVersion
static const char* WindowsVersionName[WINDOWS_MAX] = {
@ -232,7 +234,7 @@ BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size)
goto out;
}
PrintStatus(0, TRUE, "%s '%s'", save?"Saved":"Opened", path);
PrintStatus(0, TRUE, save?lmprintf(MSG_216, path):lmprintf(MSG_215, path));
ret = TRUE;
out:

View File

@ -31,6 +31,7 @@
#include "msapi_utf8.h"
#include "rufus.h"
#include "resource.h"
#include "localization.h"
/*
* Globals
@ -40,7 +41,8 @@ HWND hStatus;
#ifdef RUFUS_DEBUG
void _uprintf(const char *format, ...)
{
char buf[4096], *p = buf;
static char buf[4096];
char* p = buf;
va_list args;
int n;
@ -50,7 +52,7 @@ void _uprintf(const char *format, ...)
p += (n < 0)?sizeof(buf)-3:n;
while((p>buf) && (isspace((unsigned char)p[-1])))
while((p>buf) && (isspaceU(p[-1])))
*--p = '\0';
*p++ = '\r';
@ -145,23 +147,11 @@ static void CALLBACK PrintStatusTimeout(HWND hwnd, UINT uMsg, UINT_PTR idEvent,
KillTimer(hMainDialog, TID_MESSAGE);
}
void PrintStatus(unsigned int duration, BOOL debug, const char *format, ...)
void PrintStatus(unsigned int duration, BOOL debug, const char* message)
{
char *p = szStatusMessage;
va_list args;
int n;
va_start(args, format);
n = safe_vsnprintf(p, sizeof(szStatusMessage)-1, format, args); // room for NUL
va_end(args);
p += (n < 0)?sizeof(szStatusMessage)-1:n;
while((p>szStatusMessage) && (isspace(p[-1])))
*--p = '\0';
*p = '\0';
if (message == NULL)
return;
safe_strcpy(szStatusMessage, sizeof(szStatusMessage), message);
if (debug)
uprintf("%s\n", szStatusMessage);
@ -192,17 +182,16 @@ char* GuidToString(const GUID* guid)
char* SizeToHumanReadable(LARGE_INTEGER size)
{
int suffix = 0;
static char str_size[24];
const char* sizes[] = { "", "KB", "MB", "GB", "TB" };
static char str_size[32];
double hr_size = (double)size.QuadPart;
while ((suffix < ARRAYSIZE(sizes)) && (hr_size >= 1024.0)) {
while ((suffix < MAX_SIZE_SUFFIXES) && (hr_size >= 1024.0)) {
hr_size /= 1024.0;
suffix++;
}
if (suffix == 0) {
safe_sprintf(str_size, sizeof(str_size), "%d bytes", (int)hr_size);
safe_sprintf(str_size, sizeof(str_size), "%d %s", (int)hr_size, lmprintf(MSG_020));
} else {
safe_sprintf(str_size, sizeof(str_size), "%0.1f %s", hr_size, sizes[suffix]);
safe_sprintf(str_size, sizeof(str_size), "%0.1f %s", hr_size, lmprintf(MSG_020 + suffix));
}
return str_size;
}
@ -210,7 +199,7 @@ char* SizeToHumanReadable(LARGE_INTEGER size)
const char* StrError(DWORD error_code)
{
if ( (!IS_ERROR(error_code)) || (SCODE_CODE(error_code) == ERROR_SUCCESS)) {
return "Success";
return lmprintf(MSG_044);
}
if (SCODE_FACILITY(error_code) != FACILITY_STORAGE) {
uprintf("StrError: non storage - %08X (%X)\n", error_code, SCODE_FACILITY(error_code));
@ -219,63 +208,61 @@ const char* StrError(DWORD error_code)
}
switch (SCODE_CODE(error_code)) {
case ERROR_GEN_FAILURE:
return "Undetermined error while formatting.";
return lmprintf(MSG_051);
case ERROR_INCOMPATIBLE_FS:
return "Cannot use the selected file system for this media.";
return lmprintf(MSG_052);
case ERROR_ACCESS_DENIED:
return "Access to the device is denied.";
return lmprintf(MSG_053);
case ERROR_WRITE_PROTECT:
return "Media is write protected.";
return lmprintf(MSG_054);
case ERROR_DEVICE_IN_USE:
return "The device is in use by another process. "
"Please close any other process that may be accessing the device.";
return lmprintf(MSG_055);
case ERROR_CANT_QUICK_FORMAT:
return "Quick format is not available for this device.";
return lmprintf(MSG_056);
case ERROR_LABEL_TOO_LONG:
return "The volume label is invalid.";
return lmprintf(MSG_057);
case ERROR_INVALID_HANDLE:
return "The device handle is invalid.";
return lmprintf(MSG_058);
case ERROR_INVALID_CLUSTER_SIZE:
return "The selected cluster size is not valid for this device.";
return lmprintf(MSG_059);
case ERROR_INVALID_VOLUME_SIZE:
return "The volume size is invalid.";
return lmprintf(MSG_060);
case ERROR_NO_MEDIA_IN_DRIVE:
return "Please insert a media in drive.";
return lmprintf(MSG_061);
case ERROR_NOT_SUPPORTED:
return "An unsupported command was received.";
return lmprintf(MSG_062);
case ERROR_NOT_ENOUGH_MEMORY:
return "Memory allocation error.";
return lmprintf(MSG_063);
case ERROR_READ_FAULT:
return "Read error.";
return lmprintf(MSG_064);
case ERROR_WRITE_FAULT:
return "Write error.";
return lmprintf(MSG_065);
case ERROR_INSTALL_FAILURE:
return "Installation failure";
return lmprintf(MSG_066);
case ERROR_OPEN_FAILED:
return "Could not open media. It may be in use by another process. "
"Please re-plug the media and try again.";
return lmprintf(MSG_067);
case ERROR_PARTITION_FAILURE:
return "Error while partitioning drive.";
return lmprintf(MSG_068);
case ERROR_CANNOT_COPY:
return "Could not copy files to target drive.";
return lmprintf(MSG_069);
case ERROR_CANCELLED:
return "Cancelled by user.";
return lmprintf(MSG_070);
case ERROR_CANT_START_THREAD:
return "Unable to create formatting thread.";
return lmprintf(MSG_071);
case ERROR_BADBLOCKS_FAILURE:
return "Bad blocks check didn't complete.";
return lmprintf(MSG_072);
case ERROR_ISO_SCAN:
return "ISO image scan failure.";
return lmprintf(MSG_073);
case ERROR_ISO_EXTRACT:
return "ISO image extraction failure.";
return lmprintf(MSG_074);
case ERROR_CANT_REMOUNT_VOLUME:
return "Unable to remount volume.";
return lmprintf(MSG_075);
case ERROR_CANT_PATCH:
return "Unable to patch/setup files for boot.";
return lmprintf(MSG_076);
case ERROR_CANT_ASSIGN_LETTER:
return "Unable to assign a drive letter.";
return lmprintf(MSG_077);
case ERROR_CANT_MOUNT_VOLUME:
return "Can't mount GUID volume.";
return lmprintf(MSG_078);
default:
uprintf("Unknown error: %08X\n", error_code);
SetLastError(error_code);

View File

@ -39,6 +39,7 @@
#include "registry.h"
#include "resource.h"
#include "license.h"
#include "localization.h"
/* The following is only available on Vista and later */
#if (_WIN32_WINNT >= 0x0600)
@ -66,6 +67,7 @@ static const SETTEXTEX friggin_microsoft_unicode_amateurs = {ST_DEFAULT, CP_UTF8
static BOOL notification_is_question;
static const notification_info* notification_more_info;
static BOOL reg_commcheck = FALSE;
static WNDPROC original_wndproc = NULL;
/*
* We need a sub-callback to read the content of the edit box on exit and update
@ -222,7 +224,7 @@ fallback:
INIT_XP_SHELL32;
memset(&bi, 0, sizeof(BROWSEINFOW));
bi.hwndOwner = hMainDialog;
bi.lpszTitle = L"Please select the installation folder:";
bi.lpszTitle = utf8_to_wchar(lmprintf(MSG_106));
bi.lpfn = BrowseInfoCallback;
// BIF_NONEWFOLDERBUTTON = 0x00000200 is unknown on MinGW
bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS |
@ -231,6 +233,7 @@ fallback:
if (pidl != NULL) {
CoTaskMemFree(pidl);
}
safe_free(bi.lpszTitle);
dialog_showing--;
}
@ -244,7 +247,7 @@ char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_des
DWORD tmp;
OPENFILENAMEA ofn;
char selected_name[MAX_PATH];
char* ext_string = NULL;
char *ext_string = NULL, *all_files = NULL;
size_t i, ext_strlen;
BOOL r;
char* filepath = NULL;
@ -259,6 +262,7 @@ char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_des
IShellItem *si_path = NULL; // Automatically freed
dialog_showing++;
memset(filter_spec, 0, sizeof(filter_spec));
INIT_VISTA_SHELL32;
if (IS_VISTA_SHELL32_AVAILABLE) {
// Setup the file extension filter table
@ -269,7 +273,7 @@ char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_des
safe_free(ext_filter);
filter_spec[0].pszName = utf8_to_wchar(ext_desc);
filter_spec[1].pszSpec = L"*.*";
filter_spec[1].pszName = L"All files";
filter_spec[1].pszName = utf8_to_wchar(lmprintf(MSG_107));
}
hr = CoCreateInstance(save?&CLSID_FileSaveDialog:&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC,
@ -305,6 +309,7 @@ char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_des
safe_free(wfilename);
safe_free(filter_spec[0].pszSpec);
safe_free(filter_spec[0].pszName);
safe_free(filter_spec[1].pszName);
if (SUCCEEDED(hr)) {
// Obtain the result of the user's interaction with the dialog.
@ -343,11 +348,12 @@ fallback:
ofn.lpstrFile = selected_name;
ofn.nMaxFile = MAX_PATH;
// Set the file extension filters
ext_strlen = safe_strlen(ext_desc) + 2*safe_strlen(ext) + sizeof(" (*.)\0*.\0All Files (*.*)\0*.*\0\0");
all_files = lmprintf(MSG_107);
ext_strlen = safe_strlen(ext_desc) + 2*safe_strlen(ext) + sizeof(" (*.)\0*.\0 (*.*)\0*.*\0\0") + safe_strlen(all_files);
ext_string = (char*)malloc(ext_strlen);
if (ext_string == NULL)
return NULL;
safe_sprintf(ext_string, ext_strlen, "%s (*.%s)\r*.%s\rAll Files (*.*)\r*.*\r\0", ext_desc, ext, ext);
safe_sprintf(ext_string, ext_strlen, "%s (*.%s)\r*.%s\r%s (*.*)\r*.*\r\0", ext_desc, ext, ext, all_files);
// Microsoft could really have picked a better delimiter!
for (i=0; i<ext_strlen; i++) {
if (ext_string[i] == '\r') {
@ -369,7 +375,7 @@ fallback:
} else {
tmp = CommDlgExtendedError();
if (tmp != 0) {
uprintf("Could not selected file for %s. Error %X\n", save?"save":"open", tmp);
uprintf("Could not select file for %s. Error %X\n", save?"save":"open", tmp);
}
}
safe_free(ext_string);
@ -435,6 +441,43 @@ void CenterDialog(HWND hDlg)
MoveWindow(hDlg, Point.x, Point.y, nWidth, nHeight, FALSE);
}
// http://stackoverflow.com/questions/431470/window-border-width-and-height-in-win32-how-do-i-get-it
SIZE GetBorderSize(HWND hDlg)
{
RECT rect = {0, 0, 0, 0};
SIZE size = {0, 0};
WINDOWINFO wi;
wi.cbSize = sizeof(WINDOWINFO);
GetWindowInfo(hDlg, &wi);
AdjustWindowRectEx(&rect, wi.dwStyle, FALSE, wi.dwExStyle);
size.cx = rect.right - rect.left;
size.cy = rect.bottom - rect.top;
return size;
}
void ResizeMoveCtrl(HWND hDlg, HWND hCtrl, int dx, int dy, int dw, int dh)
{
RECT rect;
POINT point;
SIZE border = {0, 0};
GetWindowRect(hCtrl, &rect);
point.x = rect.left;
point.y = rect.top;
ScreenToClient(hDlg, &point);
GetClientRect(hCtrl, &rect);
// If we're dealing with a dialog, we must take the border into account
if (hCtrl == hDlg)
border = GetBorderSize(hDlg);
MoveWindow(hCtrl, point.x + (int)(fScale*(float)dx), point.y + (int)(fScale*(float)dy),
(rect.right - rect.left) + (int)(fScale*(float)dw + border.cx),
(rect.bottom - rect.top) + border.cy, TRUE);
InvalidateRect(hCtrl, NULL, TRUE);
}
/*
* License callback
*/
@ -442,6 +485,7 @@ INT_PTR CALLBACK LicenseCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM
{
switch (message) {
case WM_INITDIALOG:
apply_localization(IDD_LICENSE, hDlg);
CenterDialog(hDlg);
SetDlgItemTextA(hDlg, IDC_LICENSE_TEXT, gplv3);
break;
@ -449,6 +493,7 @@ INT_PTR CALLBACK LicenseCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM
switch (LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
reset_localization(IDD_LICENSE);
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
@ -463,7 +508,7 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
{
int i;
const int edit_id[2] = {IDC_ABOUT_BLURB, IDC_ABOUT_COPYRIGHTS};
char about_blurb[1024];
char about_blurb[2048];
const char* edit_text[2] = {about_blurb, additional_copyrights};
HWND hEdit[2];
TEXTRANGEW tr;
@ -472,12 +517,15 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
switch (message) {
case WM_INITDIALOG:
// Execute dialog localization
apply_localization(IDD_ABOUTBOX, hDlg);
SetTitleBarIcon(hDlg);
CenterDialog(hDlg);
if (reg_commcheck)
ShowWindow(GetDlgItem(hDlg, IDC_ABOUT_UPDATES), SW_SHOW);
safe_sprintf(about_blurb, sizeof(about_blurb), about_blurb_format,
rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
safe_sprintf(about_blurb, sizeof(about_blurb), about_blurb_format, lmprintf(MSG_174),
lmprintf(MSG_175, rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]),
lmprintf(MSG_176), lmprintf(MSG_177), lmprintf(MSG_178));
for (i=0; i<ARRAYSIZE(hEdit); i++) {
hEdit[i] = GetDlgItem(hDlg, edit_id[i]);
SendMessage(hEdit[i], EM_AUTOURLDETECT, 1, 0);
@ -510,13 +558,14 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
switch (LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
reset_localization(IDD_ABOUTBOX);
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
case IDC_ABOUT_LICENSE:
DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_LICENSE), hDlg, LicenseCallback);
DialogBoxW(hMainInstance, MAKEINTRESOURCEW(IDD_LICENSE), hDlg, LicenseCallback);
break;
case IDC_ABOUT_UPDATES:
DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_UPDATE_POLICY), hDlg, UpdateCallback);
DialogBoxW(hMainInstance, MAKEINTRESOURCEW(IDD_UPDATE_POLICY), hDlg, UpdateCallback);
break;
}
break;
@ -528,7 +577,7 @@ INT_PTR CreateAboutBox(void)
{
INT_PTR r;
dialog_showing++;
r = DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_ABOUTBOX), hMainDialog, AboutCallback);
r = DialogBoxW(hMainInstance, MAKEINTRESOURCEW(IDD_ABOUTBOX), hMainDialog, AboutCallback);
dialog_showing--;
return r;
}
@ -547,6 +596,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP
switch (message) {
case WM_INITDIALOG:
apply_localization(IDD_NOTIFICATION, hDlg);
white_brush = CreateSolidBrush(WHITE);
separator_brush = CreateSolidBrush(SEPARATOR_GREY);
SetTitleBarIcon(hDlg);
@ -557,11 +607,11 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP
}
// Set the dialog title
if (szMessageTitle != NULL) {
SetWindowTextA(hDlg, szMessageTitle);
SetWindowTextU(hDlg, szMessageTitle);
}
// Enable/disable the buttons and set text
if (!notification_is_question) {
SetWindowTextA(GetDlgItem(hDlg, IDNO), "Close");
SetWindowTextU(GetDlgItem(hDlg, IDNO), lmprintf(MSG_006));
} else {
ShowWindow(GetDlgItem(hDlg, IDYES), SW_SHOW);
}
@ -570,7 +620,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP
}
// Set the control text
if (szMessageText != NULL) {
SetWindowTextA(GetDlgItem(hDlg, IDC_NOTIFICATION_TEXT), szMessageText);
SetWindowTextU(GetDlgItem(hDlg, IDC_NOTIFICATION_TEXT), szMessageText);
}
return (INT_PTR)TRUE;
case WM_CTLCOLORSTATIC:
@ -599,7 +649,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP
return (INT_PTR)TRUE;
case IDC_MORE_INFO:
if (notification_more_info != NULL)
DialogBoxA(hMainInstance, MAKEINTRESOURCEA(notification_more_info->id),
DialogBoxW(hMainInstance, MAKEINTRESOURCEW(notification_more_info->id),
hDlg, notification_more_info->callback);
break;
}
@ -937,17 +987,19 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
HWND hPolicy;
static HWND hFrequency, hBeta;
int32_t freq;
char update_policy_text[4096];
switch (message) {
case WM_INITDIALOG:
apply_localization(IDD_UPDATE_POLICY, hDlg);
SetTitleBarIcon(hDlg);
CenterDialog(hDlg);
hFrequency = GetDlgItem(hDlg, IDC_UPDATE_FREQUENCY);
hBeta = GetDlgItem(hDlg, IDC_INCLUDE_BETAS);
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Disabled"), -1));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Daily (Default)"), 86400));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Weekly"), 604800));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Monthly"), 2629800));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, lmprintf(MSG_013)), -1));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, lmprintf(MSG_030, lmprintf(MSG_014))), 86400));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, lmprintf(MSG_015)), 604800));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, lmprintf(MSG_016)), 2629800));
freq = ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL);
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NOW), (freq != 0));
EnableWindow(hBeta, (freq >= 0));
@ -966,16 +1018,19 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 3));
break;
default:
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Custom"), freq));
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, lmprintf(MSG_017)), freq));
IGNORE_RETVAL(ComboBox_SetCurSel(hFrequency, 4));
break;
}
IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "Yes"));
IGNORE_RETVAL(ComboBox_AddStringU(hBeta, "No"));
IGNORE_RETVAL(ComboBox_AddStringU(hBeta, lmprintf(MSG_008)));
IGNORE_RETVAL(ComboBox_AddStringU(hBeta, lmprintf(MSG_009)));
IGNORE_RETVAL(ComboBox_SetCurSel(hBeta, GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS)?0:1));
hPolicy = GetDlgItem(hDlg, IDC_POLICY);
SendMessage(hPolicy, EM_AUTOURLDETECT, 1, 0);
SendMessageA(hPolicy, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update_policy);
safe_sprintf(update_policy_text, sizeof(update_policy_text), update_policy, lmprintf(MSG_179),
lmprintf(MSG_180), lmprintf(MSG_181), lmprintf(MSG_182), lmprintf(MSG_183), lmprintf(MSG_184),
lmprintf(MSG_185), lmprintf(MSG_186));
SendMessageA(hPolicy, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update_policy_text);
SendMessage(hPolicy, EM_SETSEL, -1, -1);
SendMessage(hPolicy, EM_SETEVENTMASK, 0, ENM_LINK);
SendMessageA(hPolicy, EM_SETBKGNDCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNFACE));
@ -984,6 +1039,7 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
switch (LOWORD(wParam)) {
case IDCLOSE:
case IDCANCEL:
reset_localization(IDD_UPDATE_POLICY);
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
case IDC_CHECK_NOW:
@ -1036,8 +1092,7 @@ BOOL SetUpdateCheck(void)
uprintf("Short name used - Disabling initial update policy prompt\n");
enable_updates = TRUE;
} else {
enable_updates = Notification(MSG_QUESTION, &more_info, APPLICATION_NAME " update policy",
"Do you want to allow " APPLICATION_NAME " to check for application updates?\n");
enable_updates = Notification(MSG_QUESTION, &more_info, lmprintf(MSG_004), lmprintf(MSG_005));
}
if (!enable_updates) {
WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, -1);
@ -1051,6 +1106,48 @@ BOOL SetUpdateCheck(void)
return TRUE;
}
static void CreateStaticFont(HDC dc, HFONT* hyperlink_font) {
TEXTMETRIC tm;
LOGFONT lf;
if (*hyperlink_font != NULL)
return;
GetTextMetrics(dc, &tm);
lf.lfHeight = tm.tmHeight;
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = tm.tmWeight;
lf.lfItalic = tm.tmItalic;
lf.lfUnderline = TRUE;
lf.lfStrikeOut = tm.tmStruckOut;
lf.lfCharSet = tm.tmCharSet;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = tm.tmPitchAndFamily;
GetTextFace(dc, LF_FACESIZE, lf.lfFaceName);
*hyperlink_font = CreateFontIndirect(&lf);
}
/*
* Work around the limitations of edit control, to display a hand cursor for hyperlinks
* NB: The LTEXT control must have SS_NOTIFY attribute for this to work
*/
INT_PTR CALLBACK subclass_callback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SETCURSOR:
if ((HWND)wParam == GetDlgItem(hDlg, IDC_WEBSITE)) {
SetCursor(LoadCursor(NULL, IDC_HAND));
return (INT_PTR)TRUE;
}
break;
}
return CallWindowProc(original_wndproc, hDlg, message, wParam, lParam);
}
/*
* New version notification dialog
*/
@ -1058,64 +1155,55 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
{
int i;
HWND hNotes;
TEXTRANGEW tr;
ENLINK* enl;
wchar_t wUrl[256];
char tmp[128];
static char* filepath = NULL;
static int download_status = 0;
STARTUPINFOA si;
PROCESS_INFORMATION pi;
HFONT hyperlink_font = NULL;
switch (message) {
case WM_INITDIALOG:
apply_localization(IDD_NEW_VERSION, hDlg);
download_status = 0;
SetTitleBarIcon(hDlg);
CenterDialog(hDlg);
// Subclass the callback so that we can change the cursor
original_wndproc = (WNDPROC)SetWindowLongPtr(hDlg, GWLP_WNDPROC, (LONG_PTR)subclass_callback);
hNotes = GetDlgItem(hDlg, IDC_RELEASE_NOTES);
SendMessage(hNotes, EM_AUTOURLDETECT, 1, 0);
SendMessageA(hNotes, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update.release_notes);
SendMessage(hNotes, EM_SETSEL, -1, -1);
SendMessage(hNotes, EM_SETEVENTMASK, 0, ENM_LINK);
safe_sprintf(tmp, sizeof(tmp), "Your version: %d.%d.%d (Build %d)",
rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
SetWindowTextA(GetDlgItem(hDlg, IDC_YOUR_VERSION), tmp);
safe_sprintf(tmp, sizeof(tmp), "Latest version: %d.%d.%d (Build %d)",
update.version[0], update.version[1], update.version[2], update.version[3]);
SetWindowTextA(GetDlgItem(hDlg, IDC_LATEST_VERSION), tmp);
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD_URL), update.download_url);
SetWindowTextU(GetDlgItem(hDlg, IDC_YOUR_VERSION), lmprintf(MSG_018,
rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]));
SetWindowTextU(GetDlgItem(hDlg, IDC_LATEST_VERSION), lmprintf(MSG_019,
update.version[0], update.version[1], update.version[2], update.version[3]));
SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD_URL), update.download_url);
SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000);
if (update.download_url == NULL)
EnableWindow(GetDlgItem(hDlg, IDC_DOWNLOAD), FALSE);
break;
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code) {
case NM_CLICK:
case NM_RETURN:
if (LOWORD(wParam) == IDC_WEBSITE) {
ShellExecuteA(hDlg, "open", RUFUS_URL, NULL, NULL, SW_SHOWNORMAL);
}
break;
case EN_LINK:
enl = (ENLINK*) lParam;
if (enl->msg == WM_LBUTTONUP) {
tr.lpstrText = wUrl;
tr.chrg.cpMin = enl->chrg.cpMin;
tr.chrg.cpMax = enl->chrg.cpMax;
SendMessageW(enl->nmhdr.hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
wUrl[ARRAYSIZE(wUrl)-1] = 0;
ShellExecuteW(hDlg, L"open", wUrl, NULL, NULL, SW_SHOWNORMAL);
}
break;
}
break;
case WM_CTLCOLORSTATIC:
if ((HWND)lParam != GetDlgItem(hDlg, IDC_WEBSITE))
return FALSE;
// Change the font for the hyperlink
SetBkMode((HDC)wParam, TRANSPARENT);
CreateStaticFont((HDC)wParam, &hyperlink_font);
SelectObject((HDC)wParam, hyperlink_font);
SetTextColor((HDC)wParam, RGB(0,0,125)); // DARK_BLUE
return (INT_PTR)CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDCLOSE:
case IDCANCEL:
reset_localization(IDD_NEW_VERSION);
safe_free(filepath);
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
case IDC_WEBSITE:
ShellExecuteA(hDlg, "open", RUFUS_URL, NULL, NULL, SW_SHOWNORMAL);
break;
case IDC_DOWNLOAD: // Also doubles as abort and launch function
switch(download_status) {
case 1: // Abort
@ -1130,17 +1218,17 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
if (!CreateProcessU(NULL, tmp, NULL, NULL, FALSE, 0, NULL, filepath, &si, &pi)) {
PrintStatus(0, FALSE, "Failed to launch new application");
PrintStatus(0, FALSE, lmprintf(MSG_214));
uprintf("Failed to launch new application: %s\n", WindowsErrorString());
} else {
PrintStatus(0, FALSE, "Launching new application...");
PrintStatus(0, FALSE, lmprintf(MSG_213));
PostMessage(hDlg, WM_COMMAND, (WPARAM)IDCLOSE, 0);
PostMessage(hMainDialog, WM_CLOSE, 0, 0);
}
break;
default: // Download
for (i=(int)safe_strlen(update.download_url); (i>0)&&(update.download_url[i]!='/'); i--);
filepath = FileDialog(TRUE, app_dir, (char*)&update.download_url[i+1], "exe", "Application");
filepath = FileDialog(TRUE, app_dir, (char*)&update.download_url[i+1], "exe", lmprintf(MSG_037));
if (filepath != NULL)
DownloadFileThreaded(update.download_url, filepath, hDlg);
break;
@ -1151,14 +1239,14 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
case UM_ISO_INIT:
FormatStatus = 0;
download_status = 1;
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Abort");
SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), lmprintf(MSG_038));
return (INT_PTR)TRUE;
case UM_ISO_EXIT:
if (wParam) {
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Launch");
SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), lmprintf(MSG_039));
download_status = 2;
} else {
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Download");
SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), lmprintf(MSG_040));
download_status = 0;
}
return (INT_PTR)TRUE;
@ -1168,7 +1256,7 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
void DownloadNewVersion(void)
{
DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_NEW_VERSION), hMainDialog, NewVersionCallback);
DialogBoxW(hMainInstance, MAKEINTRESOURCEW(IDD_NEW_VERSION), hMainDialog, NewVersionCallback);
}
void SetTitleBarIcon(HWND hDlg)

View File

@ -28,6 +28,7 @@
#include "rufus.h"
#include "resource.h"
#include "localization.h"
#include "syslinux.h"
#include "syslxfs.h"
@ -91,7 +92,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter)
int dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType));
BOOL use_v5 = (dt == DT_SYSLINUX_V5) || ((dt == DT_ISO) && (iso_report.has_syslinux_v5));
PrintStatus(0, TRUE, "Installing Syslinux v%d...", use_v5?5:4);
PrintStatus(0, TRUE, lmprintf(MSG_234, use_v5?5:4));
ldlinux_path[0] = drive_letter;