diff --git a/src/badblocks.c b/src/badblocks.c index dfc3807a..5288bb5b 100644 --- a/src/badblocks.c +++ b/src/badblocks.c @@ -328,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, lmprintf(MSG_235, + PrintStatus(0, FALSE, MSG_235, cur_pattern, nr_pattern, percent, num_read_errors, num_write_errors, - num_corruption_errors)); + num_corruption_errors); UpdateProgress(OP_BADBLOCKS, (((cur_pattern-1)*100.0f) + percent) / nr_pattern); } @@ -359,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, lmprintf(MSG_236)); + PrintStatus(3500, FALSE, MSG_236); } else { bpattern[0] = 0; for (i = 0; i < sizeof(bpattern); i++) { @@ -376,7 +376,7 @@ static void pattern_fill(unsigned char *buffer, unsigned int pattern, else i--; } - PrintStatus(3500, FALSE, lmprintf(MSG_237, bpattern[i])); + PrintStatus(3500, FALSE, MSG_237, bpattern[i]); cur_pattern++; } } diff --git a/src/drive.c b/src/drive.c index 030838f8..0d0c63ea 100644 --- a/src/drive.c +++ b/src/drive.c @@ -691,7 +691,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m DWORD size; LONGLONG size_in_sectors; - PrintStatus(0, TRUE, lmprintf(MSG_238, PartitionTypeName[partition_style])); + PrintStatus(0, TRUE, 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... @@ -838,7 +838,7 @@ BOOL DeletePartitions(HANDLE hDrive) DWORD size; CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}}; - PrintStatus(0, TRUE, lmprintf(MSG_239)); + PrintStatus(0, TRUE, MSG_239); size = sizeof(CreateDisk); r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK, diff --git a/src/format.c b/src/format.c index ee889022..768d092f 100644 --- a/src/format.c +++ b/src/format.c @@ -70,16 +70,16 @@ static BOOLEAN __stdcall FormatExCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, switch(Command) { case FCC_PROGRESS: percent = (DWORD*)pData; - PrintStatus(0, FALSE, lmprintf(MSG_217, *percent)); + PrintStatus(0, FALSE, MSG_217, *percent); UpdateProgress(OP_FORMAT, 1.0f * (*percent)); break; case FCC_STRUCTURE_PROGRESS: // No progress on quick format - PrintStatus(0, TRUE, lmprintf(MSG_218, ++task_number, nb_steps[fs_index])); + PrintStatus(0, TRUE, 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, lmprintf(MSG_218, nb_steps[fs_index], nb_steps[fs_index])); + PrintStatus(0, TRUE, 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"); @@ -154,7 +154,7 @@ static BOOLEAN __stdcall ChkdskCallback(FILE_SYSTEM_CALLBACK_COMMAND Command, DW case FCC_PROGRESS: case FCC_CHECKDISK_PROGRESS: percent = (DWORD*)pData; - PrintStatus(0, FALSE, lmprintf(MSG_219, *percent)); + PrintStatus(0, FALSE, MSG_219, *percent); break; case FCC_DONE: if(*(BOOLEAN*)pData == FALSE) { @@ -369,7 +369,7 @@ static BOOL FormatFAT32(DWORD DriveIndex) // Debug temp vars ULONGLONG FatNeeded, ClusterCount; - PrintStatus(0, TRUE, lmprintf(MSG_222, "Large FAT32")); + PrintStatus(0, TRUE, MSG_222, "Large FAT32"); VolumeId = GetVolumeID(); // Open the drive and lock it @@ -564,7 +564,7 @@ static BOOL FormatFAT32(DWORD DriveIndex) if (GetTickCount() > LastRefresh + 25) { LastRefresh = GetTickCount(); format_percent = (100.0f*i)/(1.0f*(SystemAreaSize+BurstSize)); - PrintStatus(0, FALSE, lmprintf(MSG_217, format_percent)); + PrintStatus(0, FALSE, MSG_217, format_percent); UpdateProgress(OP_FORMAT, format_percent); } if (IS_ERROR(FormatStatus)) goto out; // For cancellation @@ -589,7 +589,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, lmprintf(MSG_229)); + PrintStatus(0, TRUE, 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"); @@ -598,7 +598,7 @@ static BOOL FormatFAT32(DWORD DriveIndex) // Set the FAT32 volume label GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel)); ToValidLabel(wLabel, TRUE); - PrintStatus(0, TRUE, lmprintf(MSG_221)); + PrintStatus(0, TRUE, MSG_221); // Handle must be closed for SetVolumeLabel to work safe_closehandle(hLogicalVolume); VolumeName = GetLogicalName(DriveIndex, TRUE, TRUE); @@ -641,9 +641,9 @@ static BOOL FormatDrive(DWORD DriveIndex) GetWindowTextU(hFileSystem, FSType, ARRAYSIZE(FSType)); fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); if ((fs == FS_UDF) && !((dur_mins == 0) && (dur_secs == 0))) { - PrintStatus(0, TRUE, lmprintf(MSG_220, FSType, dur_mins, dur_secs)); + PrintStatus(0, TRUE, MSG_220, FSType, dur_mins, dur_secs); } else { - PrintStatus(0, TRUE, lmprintf(MSG_222, FSType)); + PrintStatus(0, TRUE, MSG_222, FSType); } VolumeName = GetLogicalName(DriveIndex, FALSE, TRUE); wVolumeName = utf8_to_wchar(VolumeName); @@ -706,7 +706,7 @@ static BOOL CheckDisk(char DriveLetter) size_t i; wDriveRoot[0] = (WCHAR)DriveLetter; - PrintStatus(0, TRUE, lmprintf(MSG_223)); + PrintStatus(0, TRUE, MSG_223); PF_INIT_OR_OUT(Chkdsk, fmifs); @@ -799,7 +799,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, lmprintf(MSG_224)); + PrintStatus(0, TRUE, MSG_224); if (pBuf == NULL) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; goto out; @@ -1199,7 +1199,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, lmprintf(MSG_225)); + PrintStatus(0, TRUE, MSG_225); hPhysicalDrive = GetPhysicalHandle(DriveIndex, TRUE, TRUE); if (hPhysicalDrive == INVALID_HANDLE_VALUE) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; @@ -1240,7 +1240,7 @@ DWORD WINAPI FormatThread(LPVOID param) } CHECK_FOR_USER_CANCEL; - PrintStatus(0, TRUE, lmprintf(MSG_226)); + PrintStatus(0, TRUE, MSG_226); AnalyzeMBR(hPhysicalDrive); if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) { AnalyzePBR(hLogicalVolume); @@ -1312,7 +1312,7 @@ DWORD WINAPI FormatThread(LPVOID param) } // Close the (unmounted) volume before formatting if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) { - PrintStatus(0, TRUE, lmprintf(MSG_227)); + PrintStatus(0, TRUE, MSG_227); if (!CloseHandle(hLogicalVolume)) { uprintf("Could not close volume: %s\n", WindowsErrorString()); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; @@ -1352,13 +1352,13 @@ DWORD WINAPI FormatThread(LPVOID param) ret = use_large_fat32?FormatFAT32(DriveIndex):FormatDrive(DriveIndex); if (!ret) { // Error will be set by FormatDrive() in FormatStatus - uprintf("Format error: %s\n", StrError(FormatStatus)); + uprintf("Format error: %s\n", StrError(FormatStatus, TRUE)); goto out; } // Thanks to Microsoft, we must fix the MBR AFTER the drive has been formatted if (pt == PARTITION_STYLE_MBR) { - PrintStatus(0, TRUE, lmprintf(MSG_228)); + PrintStatus(0, TRUE, MSG_228); if (!WriteMBR(hPhysicalDrive)) { if (!IS_ERROR(FormatStatus)) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; @@ -1405,7 +1405,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, lmprintf(MSG_229)); + PrintStatus(0, TRUE, MSG_229); if (!WritePBR(hLogicalVolume)) { if (!IS_ERROR(FormatStatus)) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; @@ -1434,7 +1434,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, lmprintf(MSG_230)); + PrintStatus(0, TRUE, MSG_230); if (!ExtractDOS(drive_name)) { if (!IS_ERROR(FormatStatus)) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; @@ -1443,7 +1443,7 @@ DWORD WINAPI FormatThread(LPVOID param) } else if (dt == DT_ISO) { if (iso_path != NULL) { UpdateProgress(OP_DOS, 0.0f); - PrintStatus(0, TRUE, lmprintf(MSG_231)); + PrintStatus(0, TRUE, MSG_231); drive_name[2] = 0; if (!ExtractISO(iso_path, drive_name, FALSE)) { if (!IS_ERROR(FormatStatus)) @@ -1452,7 +1452,7 @@ DWORD WINAPI FormatThread(LPVOID param) } if ((bt == BT_UEFI) && (!iso_report.has_efi) && (iso_report.has_win7_efi)) { // TODO: Check ISO with EFI only - PrintStatus(0, TRUE, lmprintf(MSG_232)); + PrintStatus(0, TRUE, MSG_232); wim_image[0] = drive_name[0]; efi_dst[0] = drive_name[0]; efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0; @@ -1475,7 +1475,7 @@ DWORD WINAPI FormatThread(LPVOID param) } } UpdateProgress(OP_FINALIZE, -1.0f); - PrintStatus(0, TRUE, lmprintf(MSG_233)); + PrintStatus(0, TRUE, MSG_233); if (IsChecked(IDC_SET_ICON)) SetAutorun(drive_name); // Issue another complete remount before we exit, to ensure we're clean diff --git a/src/localization.c b/src/localization.c index 8095814c..e685ebe0 100644 --- a/src/localization.c +++ b/src/localization.c @@ -72,13 +72,17 @@ struct list_head locale_list = {NULL, NULL}; char *loc_filename = NULL, *embedded_loc_filename = "embedded.loc"; /* Message table */ -char* msg_table[MSG_MAX-MSG_000] = {0}; +char* default_msg_table[MSG_MAX-MSG_000] = {0}; +char* current_msg_table[MSG_MAX-MSG_000] = {0}; +char** msg_table = NULL; -static void mtab_destroy(void) +static void mtab_destroy(BOOL reinit) { size_t j; for (j=0; jtxt[0], msg_prefix, 4) == 0) { if (lcmd->command != LC_TEXT) { - luprint("only the 't' command can be applied to a message (MSG_###)\n"); + luprint("only the [t]ext command can be applied to a message (MSG_###)\n"); goto err; } // Try to convert the numeric part of a MSG_#### to a numeric @@ -406,6 +408,12 @@ BOOL dispatch_loc_cmd(loc_cmd* lcmd) } } + // Don't process UI commands when we're dealing with the default + if (msg_table == default_msg_table) { + free_loc_cmd(lcmd); + return TRUE; + } + switch(lcmd->command) { // NB: For commands that take an ID, ctrl_id is always a valid index at this stage case LC_TEXT: @@ -425,7 +433,7 @@ BOOL dispatch_loc_cmd(loc_cmd* lcmd) base_locale = get_locale_from_name(lcmd->txt[0], FALSE); if (base_locale != NULL) { uprintf("localization: using locale base '%s'\n", lcmd->txt[0]); - get_loc_data_file(NULL, (long)base_locale->num[0], (long)base_locale->num[1], base_locale->line_nr); + get_loc_data_file(NULL, base_locale); } else { luprintf("locale base '%s' not found - ignoring", lcmd->txt[0]); } @@ -558,6 +566,70 @@ char* lmprintf(int msg_id, ...) return buf[buf_id++]; } +/* + * Display a localized message on the status bar as well as its English counterpart in the + * log (if debug is set). If duration is non zero, ensures that message is displayed for at + * least duration ms, regardless of any other incoming message + */ +static BOOL bStatusTimerArmed = FALSE; +char szStatusMessage[256] = { 0 }; +static void CALLBACK PrintStatusTimeout(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + bStatusTimerArmed = FALSE; + // potentially display lower priority message that was overridden + SendMessageLU(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTW, SBT_OWNERDRAW, szStatusMessage); + KillTimer(hMainDialog, TID_MESSAGE); +} + +void PrintStatus(unsigned int duration, BOOL debug, int msg_id, ...) +{ + char *format = NULL, buf[sizeof(szStatusMessage)]; + va_list args; + + if (msg_id < 0) { + //A negative msg_id clears the status + SendMessageLU(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTW, SBT_OWNERDRAW, ""); + return; + } + + if ((msg_id <= MSG_000) || (msg_id >= MSG_MAX)) { + uprintf("PrintStatus: invalid MSG_ID\n"); + return; + } + + format = msg_table[msg_id - MSG_000]; + if (format == NULL) { + safe_sprintf(szStatusMessage, sizeof(szStatusMessage), "MSG_%03d UNTRANSLATED", msg_id - MSG_000); + return; + } + + va_start(args, msg_id); + safe_vsnprintf(szStatusMessage, sizeof(szStatusMessage), format, args); + va_end(args); + szStatusMessage[sizeof(szStatusMessage)-1] = '\0'; + + if ((duration) || (!bStatusTimerArmed)) { + SendMessageLU(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTW, SBT_OWNERDRAW, szStatusMessage); + } + + if (duration) { + SetTimer(hMainDialog, TID_MESSAGE, duration, PrintStatusTimeout); + bStatusTimerArmed = TRUE; + } + + if (debug) { + format = default_msg_table[msg_id - MSG_000]; + if (format == NULL) { + safe_sprintf(buf, sizeof(szStatusMessage), "(default) MSG_%03d UNTRANSLATED", msg_id - MSG_000); + return; + } + va_start(args, msg_id); + safe_vsnprintf(buf, sizeof(szStatusMessage)-1, format, args); + va_end(args); + uprintf(buf); + } +} + /* * These 2 functions are used to set the current locale * If fallback is true, the call will fall back to use the first @@ -611,3 +683,20 @@ loc_cmd* get_locale_from_name(char* locale_name, BOOL fallback) uprintf("localization: could not find locale for name '%s'. Will default to '%s'\n", locale_name, lcmd->txt[0]); return lcmd; } + +/* + * This call is used to toggle the issuing of messages with the default locale + * (usually en-US) instead of the current (usually non en) one. + */ +void toggle_default_locale(void) +{ + static char** old_msg_table = NULL; + + if (old_msg_table == NULL) { + old_msg_table = msg_table; + msg_table = default_msg_table; + } else { + msg_table = old_msg_table; + old_msg_table = NULL; + } +} diff --git a/src/localization.h b/src/localization.h index 0290c3d1..3137598f 100644 --- a/src/localization.h +++ b/src/localization.h @@ -146,8 +146,10 @@ typedef struct loc_dlg_list_struct { extern const loc_parse parse_cmd[9]; extern struct list_head locale_list; +extern char *default_msg_table[], *current_msg_table[], **msg_table; int loc_line_nr; char *loc_filename, *embedded_loc_filename; +BOOL en_msg_mode; void free_loc_cmd(loc_cmd* lcmd); BOOL dispatch_loc_cmd(loc_cmd* lcmd); @@ -161,7 +163,8 @@ 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); +BOOL get_loc_data_file(const char* filename, loc_cmd* lcmd); void free_locale_list(void); loc_cmd* get_locale_from_lcid(int lcid, BOOL fallback); loc_cmd* get_locale_from_name(char* locale_name, BOOL fallback); +void toggle_default_locale(void); diff --git a/src/net.c b/src/net.c index e9e3eef8..dadc1080 100644 --- a/src/net.c +++ b/src/net.c @@ -264,7 +264,7 @@ BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog) SendMessage(hProgressDialog, UM_ISO_INIT, 0, 0); } - PrintStatus(0, FALSE, lmprintf(MSG_240, file)); + PrintStatus(0, FALSE, MSG_240, file); uprintf("Downloading %s from %s\n", file, url); if (!InternetCrackUrlA(url, (DWORD)safe_strlen(url), 0, &UrlParts)) { @@ -341,7 +341,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, lmprintf(MSG_241, (100.0f*dwSize)/(1.0f*dwTotalSize))); + PrintStatus(0, FALSE, 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; @@ -363,9 +363,9 @@ out: if (fd != NULL) fclose(fd); if (!r) { _unlink(file); - PrintStatus(0, FALSE, lmprintf(MSG_242)); + PrintStatus(0, FALSE, MSG_242); SetLastError(error_code); - MessageBoxU(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus):WinInetErrorString(), + MessageBoxU(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus, FALSE):WinInetErrorString(), lmprintf(MSG_044), MB_OK|MB_ICONERROR); } if (hRequest) InternetCloseHandle(hRequest); @@ -456,7 +456,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) } } - PrintStatus(3000, TRUE, lmprintf(MSG_243)); + PrintStatus(3000, TRUE, MSG_243); status++; // 1 if (!GetVersionExA(&os_version)) { @@ -588,14 +588,14 @@ out: if (hSession) InternetCloseHandle(hSession); switch(status) { case 1: - PrintStatus(3000, TRUE, lmprintf(MSG_244)); + PrintStatus(3000, TRUE, MSG_244); break; case 2: - PrintStatus(3000, TRUE, lmprintf(MSG_245)); + PrintStatus(3000, TRUE, MSG_245); break; case 3: case 4: - PrintStatus(3000, FALSE, lmprintf(found_new_version?MSG_246:MSG_247)); + PrintStatus(3000, FALSE, found_new_version?MSG_246:MSG_247); default: break; } diff --git a/src/parser.c b/src/parser.c index 5f3e71ba..65a5516b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -353,31 +353,60 @@ out: * 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) +BOOL get_loc_data_file(const char* filename, loc_cmd* lcmd) { size_t bufsize = 1024; static FILE* fd = NULL; - char *ret = NULL, *buf = NULL; + char *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; + int start_line, old_loc_line_nr; + BOOL ret = FALSE, eol = FALSE, escape_sequence = FALSE, reentrant = (fd != NULL); + long offset, cur_offset = -1, end_offset; + // The default locale is always the first one + loc_cmd* default_locale = list_entry(locale_list.next, loc_cmd, list); - 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 { + // We keep a default message table populated with the en-US messages. + // Ensure that it got properly initialized first. + if ((msg_table == NULL) && (lcmd != NULL)) { + uprintf("localization: default message table has not been populated!"); + return FALSE; + } else if ((msg_table != NULL) && (lcmd == NULL)) { + uprintf("localization: default message table has already been populated!"); + return FALSE; + } + + if (!reentrant) { if ((filename == NULL) || (filename[0] == 0)) - return NULL; + return FALSE; + if (lcmd == default_locale) { + // The default locale has already been populated => nothing to do + msg_table = default_msg_table; + return TRUE; + } + if (lcmd == NULL) { + // Fill the default table + lcmd = default_locale; + msg_table = default_msg_table; + } else { + // Fill the current table + msg_table = current_msg_table; + } free_dialog_list(); fd = open_loc_file(filename); if (fd == NULL) goto out; + } else { + // 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; } + + offset = (long)lcmd->num[0]; + end_offset = (long)lcmd->num[1]; + start_line = lcmd->line_nr; loc_line_nr = start_line; buf = (char*) malloc(bufsize); if (buf == NULL) { @@ -489,6 +518,7 @@ char* get_loc_data_file(const char* filename, long offset, long end_offset, int } } } while(1); + ret = TRUE; out: // Don't close on a reentrant call diff --git a/src/rufus.c b/src/rufus.c index 2e890a03..f1a9305a 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -144,6 +144,7 @@ static float slot_end[OP_MAX+1]; // shifted +1 so that we can substract 1 to OP static float previous_end; // TODO: Remember to update copyright year in both license.h and the RC when the year changes! +// Also localization_data.sh #define KB 1024LL #define MB 1048576LL @@ -1074,7 +1075,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, lmprintf(MSG_201)); + PrintStatus(0, FALSE, MSG_201); uprintf("Cancelling (from ISO proc.)\n"); EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), FALSE); if (format_thid != NULL) @@ -1102,10 +1103,10 @@ DWORD WINAPI ISOScanThread(LPVOID param) if (iso_path == NULL) goto out; - PrintStatus(0, TRUE, lmprintf(MSG_202)); + PrintStatus(0, TRUE, MSG_202); if (!ExtractISO(iso_path, "", TRUE)) { SendMessage(hISOProgressDlg, UM_ISO_EXIT, 0, 0); - PrintStatus(0, TRUE, lmprintf(MSG_203)); + PrintStatus(0, TRUE, MSG_203); safe_free(iso_path); goto out; } @@ -1136,7 +1137,7 @@ DWORD WINAPI ISOScanThread(LPVOID param) fclose(fd); use_own_c32[i] = TRUE; } else { - PrintStatus(0, FALSE, lmprintf(MSG_204, old_c32_name[i])); + PrintStatus(0, FALSE, 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])); @@ -1153,7 +1154,7 @@ DWORD WINAPI ISOScanThread(LPVOID param) SetFSFromISO(); SetMBRProps(); for (i=(int)safe_strlen(iso_path); (i>0)&&(iso_path[i]!='\\'); i--); - PrintStatus(0, TRUE, lmprintf(MSG_205, &iso_path[i+1])); + PrintStatus(0, TRUE, 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) { @@ -1297,7 +1298,7 @@ static BOOL BootCheck(void) uprintf("Will reuse '%s' for Syslinux v5\n", ldlinux_name); fclose(fd); } else { - PrintStatus(0, FALSE, lmprintf(MSG_206, ldlinux_name)); + PrintStatus(0, FALSE, MSG_206, ldlinux_name); // Syslinux v5.0 or later requires a '%s' file to be installed r = MessageBoxU(hMainDialog, lmprintf(MSG_104, ldlinux_name, ldlinux_name), lmprintf(MSG_103, ldlinux_name), MB_YESNOCANCEL|MB_ICONWARNING); @@ -1477,7 +1478,7 @@ void InitDialog(HWND hDlg) static void PrintStatus2000(const char* str, BOOL val) { - PrintStatus(2000, FALSE, (lmprintf((val)?MSG_250:MSG_251, str))); + PrintStatus(2000, FALSE, (val)?MSG_250:MSG_251, str); } void ShowLanguageMenu(HWND hDlg) @@ -1607,7 +1608,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA // Operation may have completed in the meantime if (format_thid != NULL) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED; - PrintStatus(0, FALSE, lmprintf(MSG_201)); + PrintStatus(0, FALSE, MSG_201); uprintf("Cancelling (from main app)\n"); // Start a timer to detect blocking operations during ISO file extraction if (iso_blocking_status >= 0) { @@ -1680,7 +1681,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA if (HIWORD(wParam) != CBN_SELCHANGE) break; nb_devices = ComboBox_GetCount(hDeviceList); - PrintStatus(0, TRUE, lmprintf((nb_devices==1)?MSG_208:MSG_209, nb_devices)); + PrintStatus(0, TRUE, (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)); @@ -1879,7 +1880,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA PostMessage(hMainDialog, UM_FORMAT_COMPLETED, 0, 0); } uprintf("\r\nFormat operation started"); - PrintStatus(0, FALSE, ""); + PrintStatus(0, FALSE, -1); timer = 0; safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); SendMessageA(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTA, @@ -1930,17 +1931,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, lmprintf(MSG_210)); + PrintStatus(0, FALSE, MSG_210); } else if (SCODE_CODE(FormatStatus) == ERROR_CANCELLED) { SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_PAUSED, 0); SetTaskbarProgressState(TASKBAR_PAUSED); - PrintStatus(0, FALSE, lmprintf(MSG_211)); + PrintStatus(0, FALSE, 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, lmprintf(MSG_212)); - Notification(MSG_ERROR, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus)), StrError(FormatStatus)); + PrintStatus(0, FALSE, MSG_212); + Notification(MSG_ERROR, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus, FALSE)), StrError(FormatStatus, FALSE)); } FormatStatus = 0; format_op_in_progress = FALSE; @@ -2128,7 +2129,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) { // Load the translation before we print the error - get_loc_data_file(loc_file, (long)selected_locale->num[0], (long)selected_locale->num[1], selected_locale->line_nr); + get_loc_data_file(loc_file, selected_locale); MessageBoxU(NULL, lmprintf(MSG_002), lmprintf(MSG_001), MB_ICONSTOP); goto out; } @@ -2151,9 +2152,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine // 0x9e disables removable and fixed drive notifications SetLGP(FALSE, &existing_key, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0x9e); + // Populate the default locale (so that we can produce English messages in the log) + get_loc_data_file(loc_file, NULL); + relaunch: 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); + get_loc_data_file(loc_file, selected_locale); // Create the main Window hDlg = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG), NULL, MainCallback); @@ -2200,7 +2204,7 @@ relaunch: // 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, lmprintf(MSG_255)); + PrintStatus(2000, FALSE, MSG_255); existing_key = FALSE; continue; } @@ -2231,7 +2235,7 @@ relaunch: } // Alt-R => Remove all the registry keys created by Rufus if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'R')) { - PrintStatus(2000, FALSE, lmprintf(DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME "\\" APPLICATION_NAME)?MSG_248:MSG_249)); + PrintStatus(2000, FALSE, 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; diff --git a/src/rufus.h b/src/rufus.h index 9f70bf88..cc5c723e 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -292,9 +292,9 @@ extern BOOL is_x64(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* message); +extern void PrintStatus(unsigned int duration, BOOL debug, int msg_id, ...); extern void UpdateProgress(int op, float percent); -extern const char* StrError(DWORD error_code); +extern const char* StrError(DWORD error_code, BOOL use_default_locale); extern char* GuidToString(const GUID* guid); extern char* SizeToHumanReadable(LARGE_INTEGER size); extern void CenterDialog(HWND hDlg); diff --git a/src/rufus.rc b/src/rufus.rc index 94e91a9e..b62f45f4 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ 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.2.357" +CAPTION "Rufus v1.4.2.358" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,291,50,14 @@ -288,8 +288,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,2,357 - PRODUCTVERSION 1,4,2,357 + FILEVERSION 1,4,2,358 + PRODUCTVERSION 1,4,2,358 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -306,13 +306,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.4.2.357" + VALUE "FileVersion", "1.4.2.358" 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.2.357" + VALUE "ProductVersion", "1.4.2.358" END END BLOCK "VarFileInfo" diff --git a/src/stdfn.c b/src/stdfn.c index 1dedcea1..10998662 100644 --- a/src/stdfn.c +++ b/src/stdfn.c @@ -300,7 +300,7 @@ BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size) goto out; } - PrintStatus(0, TRUE, save?lmprintf(MSG_216, path):lmprintf(MSG_215, path)); + PrintStatus(0, TRUE, save?MSG_216:MSG_215, path); ret = TRUE; out: diff --git a/src/stdio.c b/src/stdio.c index 54c32ebc..d3819d32 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -134,38 +134,6 @@ static char err_string[256] = {0}; return err_string; } -/* - * Display a message on the status bar. If duration is non zero, ensures that message - * is displayed for at least duration ms, regardless of any other incoming message - */ -static BOOL bStatusTimerArmed = FALSE; -char szStatusMessage[256] = { 0 }; -static void CALLBACK PrintStatusTimeout(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) -{ - bStatusTimerArmed = FALSE; - // potentially display lower priority message that was overridden - SendMessageLU(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTW, SBT_OWNERDRAW, szStatusMessage); - KillTimer(hMainDialog, TID_MESSAGE); -} - -void PrintStatus(unsigned int duration, BOOL debug, const char* message) -{ - if (message == NULL) - return; - safe_strcpy(szStatusMessage, sizeof(szStatusMessage), message); - if (debug) - uprintf("%s\n", szStatusMessage); - - if ((duration) || (!bStatusTimerArmed)) { - SendMessageLU(GetDlgItem(hMainDialog, IDC_STATUS), SB_SETTEXTW, SBT_OWNERDRAW, szStatusMessage); - } - - if (duration) { - SetTimer(hMainDialog, TID_MESSAGE, duration, PrintStatusTimeout); - bStatusTimerArmed = TRUE; - } -} - char* GuidToString(const GUID* guid) { static char guid_string[MAX_GUID_STRING_LENGTH]; @@ -196,7 +164,7 @@ char* SizeToHumanReadable(LARGE_INTEGER size) return str_size; } -const char* StrError(DWORD error_code) +const char* _StrError(DWORD error_code) { if ( (!IS_ERROR(error_code)) || (SCODE_CODE(error_code) == ERROR_SUCCESS)) { return lmprintf(MSG_044); @@ -269,3 +237,14 @@ const char* StrError(DWORD error_code) return WindowsErrorString(); } } + +const char* StrError(DWORD error_code, BOOL use_default_locale) +{ + const char* ret; + if (use_default_locale) + toggle_default_locale(); + ret = _StrError(error_code); + if (use_default_locale) + toggle_default_locale(); + return ret; +} diff --git a/src/stdlg.c b/src/stdlg.c index aa168676..c2a69718 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -1206,11 +1206,11 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR memset(&pi, 0, sizeof(pi)); si.cb = sizeof(si); if (!CreateProcessU(filepath, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { - PrintStatus(0, FALSE, lmprintf(MSG_214)); + PrintStatus(0, FALSE, MSG_214); // TODO: produce a message box and add a retry, as the file may be scanned by the Antivirus uprintf("Failed to launch new application: %s\n", WindowsErrorString()); } else { - PrintStatus(0, FALSE, lmprintf(MSG_213)); + PrintStatus(0, FALSE, MSG_213); PostMessage(hDlg, WM_COMMAND, (WPARAM)IDCLOSE, 0); PostMessage(hMainDialog, WM_CLOSE, 0, 0); } diff --git a/src/syslinux.c b/src/syslinux.c index b3b70cf7..06a7da7d 100644 --- a/src/syslinux.c +++ b/src/syslinux.c @@ -92,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, lmprintf(MSG_234, use_v5?5:4)); + PrintStatus(0, TRUE, MSG_234, use_v5?5:4); ldlinux_path[0] = drive_letter;