mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[localization] improve message generation and cleanup
This commit is contained in:
parent
0c8d0e0c60
commit
79c16c0d14
7 changed files with 196 additions and 145 deletions
|
@ -1,11 +1,10 @@
|
||||||
l "English" 0x0409, 0x0809, 0x0c09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x3809, 0x3c09, 0x4009, 0x4409, 0x4809
|
l "English" 0x0409, 0x0809, 0x0c09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x3809, 0x3c09, 0x4009, 0x4409, 0x4809
|
||||||
# TODO: replace 'p' with 's' for section
|
s IDD_MESSAGES
|
||||||
p IDD_MESSAGES
|
|
||||||
t MSG_001 "WARNING: ALL DATA ON DEVICE '%s' WILL BE DESTROYED.\n"
|
t MSG_001 "WARNING: ALL DATA ON DEVICE '%s' WILL BE DESTROYED.\n"
|
||||||
"To continue with this operation, click OK. To quit click CANCEL."
|
"To continue with this operation, click OK. To quit click CANCEL."
|
||||||
|
|
||||||
l "French" 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c
|
l "French" 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c
|
||||||
p IDD_DIALOG
|
s IDD_DIALOG
|
||||||
t IDS_FORMATOPTIONS_TXT "Options de Formattage "
|
t IDS_FORMATOPTIONS_TXT "Options de Formattage "
|
||||||
t IDS_LABEL_TXT "Nouveau label"
|
t IDS_LABEL_TXT "Nouveau label"
|
||||||
t IDS_FILESYSTEM_TXT "Système de fichier"
|
t IDS_FILESYSTEM_TXT "Système de fichier"
|
||||||
|
@ -16,14 +15,14 @@ t IDC_BADBLOCKS "Vérification de mauvais blocs:"
|
||||||
t IDC_QUICKFORMAT "Formattage rapide"
|
t IDC_QUICKFORMAT "Formattage rapide"
|
||||||
t IDC_BOOT "Disque de démarrage avec:"
|
t IDC_BOOT "Disque de démarrage avec:"
|
||||||
t IDC_SET_ICON "Ajouter un label étendu et une icône"
|
t IDC_SET_ICON "Ajouter un label étendu et une icône"
|
||||||
m IDC_ADVANCED +18 0
|
m IDC_ADVANCED +36 0
|
||||||
|
|
||||||
p IDD_MESSAGES
|
s IDD_MESSAGES
|
||||||
t MSG_001 "ATTENTION: TOUTES LES DONNEES SUR LE VOLUME '%s' VONT ETRE EFFACEES.\n"
|
t MSG_001 "ATTENTION: TOUTES LES DONNEES SUR LE VOLUME '%s' VONT ETRE EFFACEES.\n"
|
||||||
"Pour continuer cette operation, cliquez sur OK.\nPour quitter cliquez sur ANNULER."
|
"Pour continuer cette operation, cliquez sur OK.\nPour quitter cliquez sur ANNULER."
|
||||||
|
|
||||||
l "Chinese (Traditional)" 0x0404, 0x0804, 0x0c04, 0x1004, 0x1404
|
l "Chinese (Traditional)" 0x0404, 0x0804, 0x0c04, 0x1004, 0x1404
|
||||||
p IDD_DIALOG
|
s IDD_DIALOG
|
||||||
t IDS_DEVICE_TXT "设备"
|
t IDS_DEVICE_TXT "设备"
|
||||||
t IDS_PARTITION_TYPE_TXT "分区计划和目标系统类型"
|
t IDS_PARTITION_TYPE_TXT "分区计划和目标系统类型"
|
||||||
t IDS_FILESYSTEM_TXT "文件系统"
|
t IDS_FILESYSTEM_TXT "文件系统"
|
||||||
|
@ -50,36 +49,36 @@ t IDC_ENABLE_FIXED_DISKS "列表固定(非flash)或USB磁盘分区"
|
||||||
t IDC_EXTRA_PARTITION "添加修复旧的BIOS(额外的分区,校准等等)"
|
t IDC_EXTRA_PARTITION "添加修复旧的BIOS(额外的分区,校准等等)"
|
||||||
t IDC_RUFUS_MBR "使用 Rufus MBR BIOS ID:"
|
t IDC_RUFUS_MBR "使用 Rufus MBR BIOS ID:"
|
||||||
|
|
||||||
p IDD_ABOUTBOX
|
s IDD_ABOUTBOX
|
||||||
t IDD_ABOUTBOX "关于 Rufus"
|
t IDD_ABOUTBOX "关于 Rufus"
|
||||||
t IDC_ABOUT_LICENSE "许可证"
|
t IDC_ABOUT_LICENSE "许可证"
|
||||||
t IDC_ABOUT_UPDATES "更新"
|
t IDC_ABOUT_UPDATES "更新"
|
||||||
t IDOK "确定"
|
t IDOK "确定"
|
||||||
|
|
||||||
p IDD_ISO_EXTRACT
|
s IDD_ISO_EXTRACT
|
||||||
t IDD_ISO_EXTRACT "复制ISO文件..."
|
t IDD_ISO_EXTRACT "复制ISO文件..."
|
||||||
t IDC_ISO_FILENAME "打开ISO映像 - 请稍候..."
|
t IDC_ISO_FILENAME "打开ISO映像 - 请稍候..."
|
||||||
t IDC_ISO_ABORT "取消"
|
t IDC_ISO_ABORT "取消"
|
||||||
|
|
||||||
p IDD_LICENSE
|
s IDD_LICENSE
|
||||||
t IDD_LICENSE "Rufus 许可证"
|
t IDD_LICENSE "Rufus 许可证"
|
||||||
t IDOK "取消"
|
t IDOK "取消"
|
||||||
|
|
||||||
p IDD_NOTIFICATION
|
s IDD_NOTIFICATION
|
||||||
t IDC_MORE_INFO "更多信息"
|
t IDC_MORE_INFO "更多信息"
|
||||||
t IDYES "是"
|
t IDYES "是"
|
||||||
t IDNO "否"
|
t IDNO "否"
|
||||||
|
|
||||||
p IDD_LOG
|
s IDD_LOG
|
||||||
t IDD_LOG "日志"
|
t IDD_LOG "日志"
|
||||||
t IDC_LOG_CLEAR "清除日志"
|
t IDC_LOG_CLEAR "清除日志"
|
||||||
t IDC_LOG_SAVE "保存日志"
|
t IDC_LOG_SAVE "保存日志"
|
||||||
t IDCANCEL "关闭日志"
|
t IDCANCEL "关闭日志"
|
||||||
|
|
||||||
p IDD_LICENSE
|
s IDD_LICENSE
|
||||||
t IDOK "取消"
|
t IDOK "取消"
|
||||||
|
|
||||||
p IDD_UPDATE_POLICY
|
s IDD_UPDATE_POLICY
|
||||||
t IDD_UPDATE_POLICY "更新方案和设置"
|
t IDD_UPDATE_POLICY "更新方案和设置"
|
||||||
t IDS_UPDATE_SETTINGS_TXT "设置"
|
t IDS_UPDATE_SETTINGS_TXT "设置"
|
||||||
t IDS_UPDATE_FREQUENCY_TXT "检查更新:"
|
t IDS_UPDATE_FREQUENCY_TXT "检查更新:"
|
||||||
|
@ -87,7 +86,7 @@ t IDS_INCLUDE_BETAS_TXT "包括测试版本:"
|
||||||
t IDC_CHECK_NOW "立即检查"
|
t IDC_CHECK_NOW "立即检查"
|
||||||
t IDCANCEL "取消"
|
t IDCANCEL "取消"
|
||||||
|
|
||||||
p IDD_NEW_VERSION
|
s IDD_NEW_VERSION
|
||||||
t IDD_NEW_VERSION "检查更新 - Rufus"
|
t IDD_NEW_VERSION "检查更新 - Rufus"
|
||||||
t IDS_NEW_VERSION_AVAIL_TXT "更新的版本可用。请下载最新版本!"
|
t IDS_NEW_VERSION_AVAIL_TXT "更新的版本可用。请下载最新版本!"
|
||||||
t IDC_WEBSITE "点击这里进入网站"
|
t IDC_WEBSITE "点击这里进入网站"
|
||||||
|
|
|
@ -35,8 +35,14 @@
|
||||||
#include "localization.h"
|
#include "localization.h"
|
||||||
#include "localization_data.h"
|
#include "localization_data.h"
|
||||||
|
|
||||||
/* 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
|
* 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] = {
|
const loc_parse parse_cmd[9] = {
|
||||||
// Translation name and Windows LCIDs it should apply to
|
// Translation name and Windows LCIDs it should apply to
|
||||||
{ 'l', LC_LOCALE, "su" }, // l "English (US)" 0x0009,0x1009
|
{ 'l', LC_LOCALE, "su" }, // l "English (US)" 0x0009,0x1009
|
||||||
|
@ -46,9 +52,8 @@ const loc_parse parse_cmd[9] = {
|
||||||
{ 'v', LC_VERSION, "ii" }, // v 1.0 // TODO: NOT IMPLEMENTED YET
|
{ 'v', LC_VERSION, "ii" }, // v 1.0 // TODO: NOT IMPLEMENTED YET
|
||||||
// Translate the text control associated with an ID
|
// Translate the text control associated with an ID
|
||||||
{ 't', LC_TEXT, "cs" }, // t IDC_CONTROL "Translation"
|
{ 't', LC_TEXT, "cs" }, // t IDC_CONTROL "Translation"
|
||||||
// Set the parent dialog to which the next commands should apply.
|
// Set the section/dialog to which the next commands should apply
|
||||||
// Use 'p NONE' for text data that is not bound to a dialog
|
{ 's', LC_SECTION, "c" }, // p IDD_DIALOG
|
||||||
{ 'p', LC_PARENT, "c" }, // p IDD_DIALOG
|
|
||||||
// Resize a dialog (dx dy pixel increment)
|
// Resize a dialog (dx dy pixel increment)
|
||||||
{ 'r', LC_RESIZE, "cii" }, // t IDC_CONTROL +10 +10
|
{ 'r', LC_RESIZE, "cii" }, // t IDC_CONTROL +10 +10
|
||||||
// Move a dialog (dx dy pixed displacement)
|
// Move a dialog (dx dy pixed displacement)
|
||||||
|
@ -60,10 +65,23 @@ const loc_parse parse_cmd[9] = {
|
||||||
// 0 = Left to right, 1 = Right to left
|
// 0 = Left to right, 1 = Right to left
|
||||||
{ 'd', LC_DIRECTION, "i" }, // d 1 // TODO: NOT IMPLEMENTED YET
|
{ 'd', LC_DIRECTION, "i" }, // d 1 // TODO: NOT IMPLEMENTED YET
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Globals */
|
||||||
int loc_line_nr;
|
int loc_line_nr;
|
||||||
char loc_filename[32];
|
|
||||||
struct list_head locale_list = {NULL, NULL};
|
struct list_head locale_list = {NULL, NULL};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
void free_loc_cmd(loc_cmd* lcmd)
|
||||||
{
|
{
|
||||||
if (lcmd == NULL)
|
if (lcmd == NULL)
|
||||||
|
@ -74,17 +92,7 @@ void free_loc_cmd(loc_cmd* lcmd)
|
||||||
free(lcmd);
|
free(lcmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loc_dlg_add(int index, loc_cmd* lcmd)
|
void free_dialog_list(void)
|
||||||
{
|
|
||||||
if ((lcmd == NULL) || (index < 0) || (index >= ARRAYSIZE(loc_dlg))) {
|
|
||||||
uprintf("loc_dlg_add: invalid parameter\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
list_add(&lcmd->list, &loc_dlg[index].list);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: rename this to something_localization()
|
|
||||||
void free_loc_dlg(void)
|
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
loc_cmd *lcmd, *next;
|
loc_cmd *lcmd, *next;
|
||||||
|
@ -110,25 +118,82 @@ void free_locale_list(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to initialize the command lists
|
* Init/destroy our various localization lists
|
||||||
*/
|
*/
|
||||||
void init_localization(void) {
|
void init_localization(void) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i=0; i<ARRAYSIZE(loc_dlg); i++)
|
for (i=0; i<ARRAYSIZE(loc_dlg); i++)
|
||||||
list_init(&loc_dlg[i].list);
|
list_init(&loc_dlg[i].list);
|
||||||
list_init(&locale_list);
|
list_init(&locale_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit_localization(void) {
|
void exit_localization(void) {
|
||||||
free_loc_dlg();
|
free_dialog_list();
|
||||||
free_locale_list();
|
free_locale_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Yada. Should be called during init
|
* Validate and store localization command data
|
||||||
* if hDlg is NULL, we try to apply the commands against an active Window
|
*
|
||||||
* if dlg_id is negative, we try to apply all
|
* 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;
|
||||||
|
|
||||||
|
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_RESIZE:
|
||||||
|
add_dialog_command(dlg_index, lcmd);
|
||||||
|
break;
|
||||||
|
case LC_SECTION:
|
||||||
|
if ((lcmd->ctrl_id-IDD_DIALOG) > ARRAYSIZE(loc_dlg)) {
|
||||||
|
luprintf("'%s' is not a section 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;
|
||||||
|
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)
|
void apply_localization(int dlg_id, HWND hDlg)
|
||||||
{
|
{
|
||||||
|
@ -202,80 +267,53 @@ void apply_localization(int dlg_id, HWND hDlg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't use isWindow() against our existing HWND to avoid this call
|
/*
|
||||||
// as handles are recycled.
|
* 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)
|
void reset_localization(int dlg_id)
|
||||||
{
|
{
|
||||||
loc_dlg[dlg_id-IDD_DIALOG].hDlg = NULL;
|
loc_dlg[dlg_id-IDD_DIALOG].hDlg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Do we need to store a revert for every action we execute here,
|
/*
|
||||||
// or do we want to reinstantiate the dialogs?
|
* Produce a formatted localized message.
|
||||||
BOOL dispatch_loc_cmd(loc_cmd* lcmd)
|
* Like printf, this call takes a variable number of argument, and uses
|
||||||
{
|
* the message ID to identify the formatted message to use.
|
||||||
size_t i;
|
* Uses a rolling list of buffers to allow concurrency
|
||||||
static int dlg_index = 0;
|
* TODO: use dynamic realloc'd buffer in case 2048 is not enough
|
||||||
|
*/
|
||||||
if (lcmd == NULL)
|
char* lmprintf(int msg_id, ...)
|
||||||
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_RESIZE:
|
|
||||||
loc_dlg_add(dlg_index, lcmd);
|
|
||||||
break;
|
|
||||||
case LC_PARENT:
|
|
||||||
if ((lcmd->ctrl_id-IDD_DIALOG) > ARRAYSIZE(loc_dlg)) {
|
|
||||||
luprintf("'%s' is not a dialog 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;
|
|
||||||
default:
|
|
||||||
free_loc_cmd(lcmd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
err:
|
|
||||||
free_loc_cmd(lcmd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* get_loc_msg(int msg_id)
|
|
||||||
{
|
{
|
||||||
|
static int buf_id = 0;
|
||||||
|
static char buf[4][2048];
|
||||||
|
char *format = NULL;
|
||||||
|
va_list args;
|
||||||
loc_cmd* lcmd;
|
loc_cmd* lcmd;
|
||||||
|
|
||||||
|
buf_id %= 4;
|
||||||
|
buf[buf_id][0] = 0;
|
||||||
list_for_each_entry(lcmd, &loc_dlg[IDD_MESSAGES-IDD_DIALOG].list, loc_cmd, list) {
|
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)) {
|
if ((lcmd->command == LC_TEXT) && (lcmd->ctrl_id == msg_id) && (lcmd->txt[1] != NULL)) {
|
||||||
return lcmd->txt[1];
|
format = lcmd->txt[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: print the message ID or something
|
|
||||||
return "UNTRANSLATED MESSAGE";
|
if (format == NULL) {
|
||||||
|
safe_sprintf(buf[buf_id], 2047, "MSG_%03d UNTRANSLATED", msg_id);
|
||||||
|
} else {
|
||||||
|
va_start(args, msg_id);
|
||||||
|
safe_vsnprintf(buf[buf_id], 2047, format, args);
|
||||||
|
va_end(args);
|
||||||
|
buf[buf_id][2047] = '\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* get_locale_from_lcid(int lcid)
|
||||||
{
|
{
|
||||||
loc_cmd* lcmd = NULL;
|
loc_cmd* lcmd = NULL;
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
// TODO: display control name on mouseover
|
// TODO: display control name on mouseover
|
||||||
// Link to http://www.resedit.net/
|
// Link to http://www.resedit.net/
|
||||||
|
|
||||||
// Commands that take a control ID *MUST* be at the top
|
|
||||||
// The last command with a control ID *MUST* be LC_TEXT
|
|
||||||
|
|
||||||
#define luprint(msg) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr)
|
#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__)
|
#define luprintf(msg, ...) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr, __VA_ARGS__)
|
||||||
|
|
||||||
|
@ -98,9 +95,10 @@ static __inline void list_del(struct list_head *entry)
|
||||||
entry->next = entry->prev = NULL;
|
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 {
|
enum loc_command_type {
|
||||||
LC_PARENT,
|
LC_SECTION,
|
||||||
LC_MOVE,
|
LC_MOVE,
|
||||||
LC_RESIZE,
|
LC_RESIZE,
|
||||||
LC_TEXT, // Delimits commands that take a Control ID and commands that don't
|
LC_TEXT, // Delimits commands that take a Control ID and commands that don't
|
||||||
|
@ -150,8 +148,8 @@ void init_localization(void);
|
||||||
void exit_localization(void);
|
void exit_localization(void);
|
||||||
void apply_localization(int dlg_id, HWND hDlg);
|
void apply_localization(int dlg_id, HWND hDlg);
|
||||||
void reset_localization(int dlg_id);
|
void reset_localization(int dlg_id);
|
||||||
void free_loc_dlg(void);
|
void free_dialog_list(void);
|
||||||
char* get_loc_msg(int id);
|
char* lmprintf(int msg_id, ...);
|
||||||
BOOL get_supported_locales(const char* filename);
|
BOOL get_supported_locales(const char* filename);
|
||||||
char* get_loc_data_file(const char* filename, long offset, long end_offset);
|
char* get_loc_data_file(const char* filename, long offset, long end_offset);
|
||||||
void free_locale_list(void);
|
void free_locale_list(void);
|
||||||
|
|
79
src/parser.c
79
src/parser.c
|
@ -38,8 +38,10 @@
|
||||||
static const char space[] = " \t";
|
static const char space[] = " \t";
|
||||||
static const wchar_t wspace[] = L" \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)
|
* 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) {
|
static loc_cmd* get_loc_cmd(char c, char* line) {
|
||||||
size_t i, j, k, l, r, ti = 0, ii = 0;
|
size_t i, j, k, l, r, ti = 0, ii = 0;
|
||||||
char *endptr, *expected_endptr, *token;
|
char *endptr, *expected_endptr, *token;
|
||||||
|
@ -151,8 +153,9 @@ err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Parse an UTF-8 localization command line
|
* Parse an UTF-8 localization command line
|
||||||
|
*/
|
||||||
static void get_loc_data_line(char* line)
|
static void get_loc_data_line(char* line)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -183,17 +186,9 @@ static void get_loc_data_line(char* line)
|
||||||
free_loc_cmd(lcmd);
|
free_loc_cmd(lcmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void *_reallocf(void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
void *ret = realloc(ptr, size);
|
|
||||||
if (!ret)
|
|
||||||
free(ptr);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First pass of parsing the locale file, to construct the list
|
* Parse a localization file, to construct the list of available locales.
|
||||||
* of locales available. The locale file must be UTF-8 with NO BOM.
|
* The locale file must be UTF-8 with NO BOM.
|
||||||
* TODO: merge this with the next call or factorize fopen
|
* TODO: merge this with the next call or factorize fopen
|
||||||
*/
|
*/
|
||||||
BOOL get_supported_locales(const char* filename)
|
BOOL get_supported_locales(const char* filename)
|
||||||
|
@ -264,9 +259,9 @@ out:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse a Rufus localization command file (UTF-8, no BOM)
|
/*
|
||||||
// TODO: detect if locale could not be found and fallback to En
|
* Parse a locale section in a localization file (UTF-8, no BOM)
|
||||||
// TODO: change the return value and return an error if locale was not found
|
*/
|
||||||
char* get_loc_data_file(const char* filename, long offset, long end_offset)
|
char* get_loc_data_file(const char* filename, long offset, long end_offset)
|
||||||
{
|
{
|
||||||
wchar_t *wfilename = NULL;
|
wchar_t *wfilename = NULL;
|
||||||
|
@ -281,7 +276,7 @@ char* get_loc_data_file(const char* filename, long offset, long end_offset)
|
||||||
if ((filename == NULL) || (filename[0] == 0))
|
if ((filename == NULL) || (filename[0] == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
free_loc_dlg();
|
free_dialog_list();
|
||||||
loc_line_nr = 0;
|
loc_line_nr = 0;
|
||||||
safe_strcpy(loc_filename, sizeof(loc_filename), filename);
|
safe_strcpy(loc_filename, sizeof(loc_filename), filename);
|
||||||
wfilename = utf8_to_wchar(filename);
|
wfilename = utf8_to_wchar(filename);
|
||||||
|
@ -405,7 +400,7 @@ char* get_loc_data_file(const char* filename, long offset, long end_offset)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
// TODO: do we really need this here?
|
// TODO: do we really need this here?
|
||||||
apply_localization(-1, NULL);
|
// apply_localization(-1, NULL);
|
||||||
if (fd != NULL)
|
if (fd != NULL)
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
safe_free(wfilename);
|
safe_free(wfilename);
|
||||||
|
@ -414,9 +409,11 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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
|
* Parse a line of UTF-16 text and return the data if it matches the 'token'
|
||||||
// modified by the parser
|
* 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)
|
static wchar_t* get_token_data_line(const wchar_t* wtoken, wchar_t* wline)
|
||||||
{
|
{
|
||||||
size_t i, r;
|
size_t i, r;
|
||||||
|
@ -469,8 +466,10 @@ static wchar_t* get_token_data_line(const wchar_t* wtoken, wchar_t* wline)
|
||||||
return (wline[r] == 0)?NULL:&wline[r];
|
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)
|
char* get_token_data_file(const char* token, const char* filename)
|
||||||
{
|
{
|
||||||
wchar_t *wtoken = NULL, *wdata= NULL, *wfilename = NULL;
|
wchar_t *wtoken = NULL, *wdata= NULL, *wfilename = NULL;
|
||||||
|
@ -514,8 +513,10 @@ out:
|
||||||
return ret;
|
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)
|
char* get_token_data_buffer(const char* token, unsigned int n, const char* buffer, size_t buffer_size)
|
||||||
{
|
{
|
||||||
unsigned int j, curly_count;
|
unsigned int j, curly_count;
|
||||||
|
@ -578,10 +579,12 @@ static __inline char* get_sanitized_token_data_buffer(const char* token, unsigne
|
||||||
return data;
|
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
|
* Parse an update data file and populates a rufus_update structure.
|
||||||
// potentially malicious, even if it comes from a supposedly trusted server.
|
* NB: since this is remote data, and we're running elevated, it *IS* considered
|
||||||
// len should be the size of the buffer, including the zero terminator
|
* 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)
|
void parse_update(char* buf, size_t len)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -628,8 +631,10 @@ void parse_update(char* buf, size_t len)
|
||||||
update.release_notes = get_sanitized_token_data_buffer("release_notes", 1, buf, 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)
|
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" };
|
const wchar_t* outmode[] = { L"w", L"w, ccs=UTF-8", L"w, ccs=UTF-16LE" };
|
||||||
|
@ -753,10 +758,12 @@ out:
|
||||||
return ret;
|
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.
|
* Search for a specific 'src' substring data for all occurrences of 'token', and replace
|
||||||
// The parsed line is of the form: [ ]token[ ]data
|
* it with 'rep'. File can be ANSI or UNICODE and is overwritten. Parameters are UTF-8.
|
||||||
// Returns a pointer to rep if replacement occurred, NULL otherwise
|
* 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)
|
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" };
|
const wchar_t* outmode[] = { L"w", L"w, ccs=UTF-8", L"w, ccs=UTF-16LE" };
|
||||||
|
|
|
@ -1458,7 +1458,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
RECT DialogRect, DesktopRect;
|
RECT DialogRect, DesktopRect;
|
||||||
int nDeviceIndex, fs, bt, i, nWidth, nHeight;
|
int nDeviceIndex, fs, bt, i, nWidth, nHeight;
|
||||||
static DWORD DeviceNum = 0, LastRefresh = 0;
|
static DWORD DeviceNum = 0, LastRefresh = 0;
|
||||||
char tmp[128], str[MAX_PATH];
|
char tmp[128];
|
||||||
static UINT uBootChecked = BST_CHECKED, uQFChecked;
|
static UINT uBootChecked = BST_CHECKED, uQFChecked;
|
||||||
static BOOL first_log_display = TRUE, user_changed_label = FALSE;
|
static BOOL first_log_display = TRUE, user_changed_label = FALSE;
|
||||||
loc_cmd* selected_locale;
|
loc_cmd* selected_locale;
|
||||||
|
@ -1786,8 +1786,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp));
|
GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp));
|
||||||
_snprintf(str, ARRAYSIZE(str), get_loc_msg(MSG_001), tmp);
|
if (MessageBoxU(hMainDialog, lmprintf(MSG_001, tmp),
|
||||||
if (MessageBoxU(hMainDialog, str, APPLICATION_NAME, MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL) {
|
APPLICATION_NAME, MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL) {
|
||||||
format_op_in_progress = FALSE;
|
format_op_in_progress = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
10
src/rufus.h
10
src/rufus.h
|
@ -342,12 +342,20 @@ extern void parse_update(char* buf, size_t len);
|
||||||
extern BOOL WimExtractCheck(void);
|
extern BOOL WimExtractCheck(void);
|
||||||
extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst);
|
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;
|
DWORD size;
|
||||||
return DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL);
|
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 */
|
/* Basic String Array */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char** Table;
|
char** Table;
|
||||||
|
|
|
@ -40,7 +40,8 @@ HWND hStatus;
|
||||||
#ifdef RUFUS_DEBUG
|
#ifdef RUFUS_DEBUG
|
||||||
void _uprintf(const char *format, ...)
|
void _uprintf(const char *format, ...)
|
||||||
{
|
{
|
||||||
char buf[4096], *p = buf;
|
static char buf[4096];
|
||||||
|
char* p = buf;
|
||||||
va_list args;
|
va_list args;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue